swarm_cluster_cli_ope 0.4.2 → 0.5.0.pre.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.
@@ -0,0 +1,14 @@
1
+ syslog facility = local3
2
+ read only = no
3
+ list = yes
4
+ auth users = root
5
+ secrets file = /tmp/rsyncd.secrets
6
+ hosts allow = 0.0.0.0/0
7
+ uid = 0
8
+ gid = 0
9
+
10
+ [archives]
11
+ comment = archives goes here
12
+ path = /
13
+ uid = root
14
+ gid = root
@@ -0,0 +1,28 @@
1
+ require 'active_support/concern'
2
+ module SwarmClusterCliOpe
3
+ module Kubernetes
4
+ module SyncConfigs
5
+ module BaseDecorator
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ delegate :namespace, :context, to: :@stack_cfgs
11
+
12
+ private
13
+
14
+ # @return [SwarmClusterCliOpe::Kubernetes::Pod]
15
+ def container
16
+ return @service if @service.is_a? SwarmClusterCliOpe::Kubernetes::Pod
17
+ @_container ||= Pod.find_by_selector(service, namespace: namespace, context: context)
18
+ end
19
+
20
+ end
21
+
22
+ # module ClassMethods
23
+
24
+ # end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,127 @@
1
+ module SwarmClusterCliOpe
2
+ module Kubernetes
3
+ module SyncConfigs
4
+ class Rsync < SwarmClusterCliOpe::SyncConfigs::Base
5
+
6
+ include BaseDecorator
7
+
8
+ # @return [String]
9
+ def local_folder
10
+ @configs[:configs][:local]
11
+ end
12
+
13
+ # @return [String]
14
+ def remote_folder
15
+ @configs[:configs][:remote]
16
+ end
17
+
18
+
19
+ # @return [SwarmClusterCliOpe::ShellCommandResponse]
20
+ def push
21
+ execute(direction: :up)
22
+ end
23
+
24
+ # @return [SwarmClusterCliOpe::ShellCommandResponse]
25
+ def pull
26
+ execute(direction: :down)
27
+ end
28
+
29
+
30
+ private
31
+
32
+ def execute(direction: :down)
33
+
34
+ if container.nil?
35
+ say "Container non trovato"
36
+ exit
37
+ end
38
+
39
+
40
+ if yes? "Attenzione, i dati locali o remoti verranno sovrascritti/cancellati?[y,yes]"
41
+
42
+ podname = container.name
43
+
44
+ if namespace.nil?
45
+ say "Mancata configurazione del namespace tramite argomento o .swarm_cluster_project"
46
+ exit
47
+ end
48
+
49
+ cmd = container.exec(['bash -c "apt update && apt install -yq rsync psmisc"'])
50
+ if cmd.execute.failed?
51
+ puts "Problemi nell'installazione di rsync nel pod"
52
+ else
53
+ cmd = container.cp_in(File.expand_path("../../rsync_cfgs/rsyncd.conf", __FILE__), "/tmp/.")
54
+ copy_1 = cmd.execute.failed?
55
+ cmd = container.cp_in(File.expand_path("../../rsync_cfgs/rsyncd.secrets", __FILE__), "/tmp/.")
56
+ copy_2 = cmd.execute.failed?
57
+ cmd = container.exec(['bash -c "chmod 600 /tmp/rsyncd.secrets && chown root /tmp/*"'])
58
+ chmod = cmd.execute.failed?
59
+ if copy_1 or copy_2 or chmod
60
+ puts "problema nella copia dei file di configurazione nel pod"
61
+ else
62
+
63
+ begin
64
+ cmd = container.exec('bash -c "rsync --daemon --config=/tmp/rsyncd.conf --verbose --log-file=/tmp/rsync.log"')
65
+ if cmd.execute.failed?
66
+ say "Rsync non Inizializzato"
67
+ else
68
+ begin
69
+ local_port = rand(30000..40000)
70
+
71
+ p = IO.popen(container.base_cmd("port-forward #{podname} #{local_port}:873").string_command)
72
+ pid = p.pid
73
+ say "PID in execuzione port forward:#{pid}"
74
+
75
+ begin
76
+
77
+ sleep 1
78
+
79
+ # lanciamo il comando quindi per far rsync
80
+ rsync_command = [
81
+ "rsync -az --no-o --no-g",
82
+ "--delete",
83
+ "--password-file=#{ File.expand_path("../../rsync_cfgs/password", __FILE__)}"
84
+ ]
85
+
86
+ if direction == :up
87
+ rsync_command << "#{local_folder}/."
88
+ rsync_command << "rsync://root@0.0.0.0:#{local_port}/archives#{remote_folder}"
89
+ else
90
+ rsync_command << "rsync://root@0.0.0.0:#{local_port}/archives#{remote_folder}/."
91
+ rsync_command << local_folder
92
+ end
93
+ say "Eseguo rsync #{rsync_command.join(" ")}"
94
+
95
+ cmd = ShellCommandExecution.new(rsync_command)
96
+ cmd.execute
97
+
98
+ ensure
99
+ sleep 1
100
+ say "Stoppo porta forwarded"
101
+ Process.kill("INT", pid)
102
+ end
103
+ ensure
104
+ say "Tolgo il servizio di rsyn"
105
+ cmd = container.exec('bash -c "killall rsync"')
106
+ cmd.execute
107
+ end
108
+ end
109
+
110
+ ensure
111
+ say "Eseguo pulizia configurazioni caricate"
112
+ cmd = container.exec('bash -c "rm -fr /tmp/rsyncd*"')
113
+ cmd.execute
114
+ end
115
+
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,9 @@
1
+ module SwarmClusterCliOpe
2
+ module Kubernetes
3
+ module SyncConfigs
4
+ class Sqlite3 < SwarmClusterCliOpe::SyncConfigs::Sqlite3
5
+ include BaseDecorator
6
+ end
7
+ end
8
+ end
9
+ end
@@ -38,7 +38,7 @@ module SwarmClusterCliOpe
38
38
  pid: nil,
39
39
  status: nil
40
40
  }
41
- logger.debug { "SHELL: #{string_command}" }
41
+ logger.info { "SHELL: #{string_command}" }
42
42
  result[:status] = Open4::popen4(string_command) do |pid, stdin, stdout, stderr|
43
43
  stdin.close
44
44
 
@@ -1,8 +1,8 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module SwarmClusterCliOpe
4
- ##
5
- # Identifica una risposta dalla shell
4
+ ##
5
+ # Identifica una risposta dalla shell
6
6
  class ShellCommandResponse
7
7
  extend Forwardable
8
8
  include LoggerConcern
@@ -28,9 +28,22 @@ module SwarmClusterCliOpe
28
28
  ##
29
29
  # Risultato, essendo sempre composto da una lista di righe in formato json, ritorniamo un array di json
30
30
  # @param [Object] object_class
31
- # @return [Array<object_class>]
32
- def result(object_class: OpenStruct)
33
- raw_result[:stdout].split("\n").collect { |s| object_class.new(JSON.parse(s)) }
31
+ # @return [Array<object_class>,Object]
32
+ def result(object_class: OpenStruct, single: false)
33
+ #tento prima di estrapolare direttamente da json e sucessivamente come array
34
+ if single
35
+ # questo per k8s, dato che abbiamo come risposta un json vero
36
+ object_class.new(JSON.parse(raw_result[:stdout]))
37
+ else
38
+ # questo nel caso siamo in swarm che ci ritorna un array di json
39
+ raw_result[:stdout].split("\n").collect { |s| object_class.new(JSON.parse(s)) }
40
+ end
41
+ end
42
+
43
+ # @param [Class<OpenStruct>] object_class
44
+ # @return [Object]
45
+ def single_obj(object_class: OpenStruct)
46
+ result(object_class: object_class, single: true)
34
47
  end
35
48
 
36
49
  #
@@ -0,0 +1,128 @@
1
+ require 'active_support/concern'
2
+
3
+ module SwarmClusterCliOpe
4
+ module StackSyncConcern
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+
9
+ desc "stacksync [DIRECTION:pull|push]", "Si occupa di scaricare|caricare,utilizzando le configurazioni presenti, i dati dallo stack remoto"
10
+ long_desc <<-LONGDESC.gsub("\n", "\x5")
11
+ le configurazioni sono contenute nell'array: sync_configs.
12
+ ogni configurazione è composta da:
13
+ {
14
+ service:""
15
+ how:""
16
+ configs:{ }
17
+ }
18
+ - service è il nome del servizio (o nel caso di k8s una stringa da utilizzare come selettore labels)
19
+ - how è il come sincronizzare, definendo la tipologia:
20
+ ---- pg -> DB TODO
21
+ ---- mysql -> DB dump con mysql
22
+ ---- sqlite3 -> DB: viene eseguita una copia del file
23
+ ---- rsync -> RSYNC
24
+ - configs: è un hash con le configurazioni per ogni tipo di sincronizzazione
25
+
26
+ Possibili CFGS per tipologia:
27
+ rsync:
28
+ --local: -> path cartella locale
29
+ --remote: -> path cartella remota (contesto del container)
30
+
31
+ sqlite3:
32
+ --local: -> path al file
33
+ --remote: -> path al file remoto (contesto del container)
34
+
35
+ mysql:
36
+ --local: -> hash di configurazioni per il DB locale
37
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
38
+ - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
39
+ - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
40
+ - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
41
+ - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
42
+ - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
43
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
44
+ --remote: -> hash di configurazioni per il DB remoto
45
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
46
+ - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
47
+ - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
48
+ - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
49
+ - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
50
+ - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
51
+ - database_name: "MYSQL_DATABASE" -> valore in chiaro, in sostituzione della variabile ambiente
52
+ pg:
53
+ --local: -> hash di configurazioni per il DB locale
54
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
55
+ - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
56
+ - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
57
+ - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
58
+ - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
59
+ - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
60
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
61
+ --remote: -> hash di configurazioni per il DB remoto
62
+ - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
63
+ - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
64
+ - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
65
+ - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
66
+ - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
67
+ - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
68
+ - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
69
+
70
+
71
+ EXAMPLE:
72
+ Esempio di sincronizzazione di un file sqlite3 e una cartella
73
+ {
74
+ "stack_name": "test1",
75
+ "sync_configs": [
76
+ {
77
+ "service": "second",
78
+ "how": "rsync",
79
+ "configs": {
80
+ "remote": "/test_bind",
81
+ "local": "./uploads"
82
+ }
83
+ },
84
+ {
85
+ "service": "test_sqlite3",
86
+ "how": "sqlite3",
87
+ "configs": {
88
+ "remote": "/cartella_sqlite3/esempio.sqlite3",
89
+ "local": "./development.sqlite3"
90
+ }
91
+ }
92
+ ]
93
+ }
94
+ LONGDESC
95
+
96
+ def stacksync(direction)
97
+ direction = case direction
98
+ when 'push'
99
+ :push
100
+ when 'pull'
101
+ :pull
102
+ else
103
+ raise "ONLY [push|pull] action accepted"
104
+ end
105
+ cfgs.env(options[:environment]) do |cfgs|
106
+ sync_cfgs = cfgs.sync_configurations
107
+ if sync_cfgs.empty?
108
+ say "Attenzione, configurazioni di sincronizzazione vuoto. Leggere la documentazione"
109
+ else
110
+ sync_cfgs.each do |sync|
111
+ say "----------->>>>>>"
112
+ say "[ #{sync.class.name} ]"
113
+ sync.send(direction)
114
+ say "COMPLETE"
115
+ say "<<<<<<-----------"
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+
122
+ end
123
+
124
+ # module ClassMethods
125
+
126
+ # end
127
+ end
128
+ end
@@ -9,7 +9,7 @@ module SwarmClusterCliOpe
9
9
  attr_accessor :configs
10
10
 
11
11
  # @param [Hash] configs
12
- # @param [Continuation] stack_cfgs
12
+ # @param [Configuration] stack_cfgs
13
13
  def initialize(stack_cfgs, configs)
14
14
  super()
15
15
  @configs = configs
@@ -0,0 +1,29 @@
1
+ require 'active_support/concern'
2
+
3
+ module SwarmClusterCliOpe
4
+ module ThorConfigurationConcern
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+
9
+ desc "config", "Visualizza le configurazioni mergiate (HOME + Project configuration[#{Configuration.cfgs_project_file_name}])"
10
+
11
+ def config
12
+ cfgs.env(options[:environment]) do
13
+ puts JSON.pretty_generate(cfgs.merged_configurations)
14
+ end
15
+ end
16
+
17
+ desc "configure_project STACK_NAME", "Genera il file di configurazione del progetto contenente il nome dello stack"
18
+
19
+ def configure_project(stack_name)
20
+ cfgs.env(options[:environment]) do |c|
21
+ c.stack_name = stack_name
22
+ c.save_project_cfgs
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module SwarmClusterCliOpe
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0.pre.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swarm_cluster_cli_ope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0.pre.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marino Bonetti
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-10 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -88,6 +88,7 @@ files:
88
88
  - Rakefile
89
89
  - exe/swarm_cli_ope
90
90
  - lib/swarm_cluster_cli_ope.rb
91
+ - lib/swarm_cluster_cli_ope/base_configuration.rb
91
92
  - lib/swarm_cluster_cli_ope/cli.rb
92
93
  - lib/swarm_cluster_cli_ope/commands/base.rb
93
94
  - lib/swarm_cluster_cli_ope/commands/compose_container.rb
@@ -97,6 +98,15 @@ files:
97
98
  - lib/swarm_cluster_cli_ope/commands/task.rb
98
99
  - lib/swarm_cluster_cli_ope/configuration.rb
99
100
  - lib/swarm_cluster_cli_ope/configuration_concern.rb
101
+ - lib/swarm_cluster_cli_ope/k8s.rb
102
+ - lib/swarm_cluster_cli_ope/kubernetes/configuration.rb
103
+ - lib/swarm_cluster_cli_ope/kubernetes/pod.rb
104
+ - lib/swarm_cluster_cli_ope/kubernetes/rsync_cfgs/password
105
+ - lib/swarm_cluster_cli_ope/kubernetes/rsync_cfgs/rsyncd.conf
106
+ - lib/swarm_cluster_cli_ope/kubernetes/rsync_cfgs/rsyncd.secrets
107
+ - lib/swarm_cluster_cli_ope/kubernetes/sync_configs/base_decorator.rb
108
+ - lib/swarm_cluster_cli_ope/kubernetes/sync_configs/rsync.rb
109
+ - lib/swarm_cluster_cli_ope/kubernetes/sync_configs/sqlite3.rb
100
110
  - lib/swarm_cluster_cli_ope/logger_concern.rb
101
111
  - lib/swarm_cluster_cli_ope/manager.rb
102
112
  - lib/swarm_cluster_cli_ope/models/base.rb
@@ -109,6 +119,7 @@ files:
109
119
  - lib/swarm_cluster_cli_ope/node.rb
110
120
  - lib/swarm_cluster_cli_ope/shell_command_execution.rb
111
121
  - lib/swarm_cluster_cli_ope/shell_command_response.rb
122
+ - lib/swarm_cluster_cli_ope/stack_sync_concern.rb
112
123
  - lib/swarm_cluster_cli_ope/sync_configs/base.rb
113
124
  - lib/swarm_cluster_cli_ope/sync_configs/base_database.rb
114
125
  - lib/swarm_cluster_cli_ope/sync_configs/copy.rb
@@ -117,6 +128,7 @@ files:
117
128
  - lib/swarm_cluster_cli_ope/sync_configs/post_gres.rb
118
129
  - lib/swarm_cluster_cli_ope/sync_configs/rsync.rb
119
130
  - lib/swarm_cluster_cli_ope/sync_configs/sqlite3.rb
131
+ - lib/swarm_cluster_cli_ope/thor_configuration_concern.rb
120
132
  - lib/swarm_cluster_cli_ope/version.rb
121
133
  - lib/swarm_cluster_cli_ope/worker.rb
122
134
  - swarm_cluster_cli_ope.gemspec
@@ -139,9 +151,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
151
  version: 2.3.0
140
152
  required_rubygems_version: !ruby/object:Gem::Requirement
141
153
  requirements:
142
- - - ">="
154
+ - - ">"
143
155
  - !ruby/object:Gem::Version
144
- version: '0'
156
+ version: 1.3.1
145
157
  requirements: []
146
158
  rubygems_version: 3.0.8
147
159
  signing_key: