swarm_cluster_cli_ope 0.4 → 0.5.0.pre.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dcf7eb87d7665ee32ead2dff9a05a3a7abb09587c6ffb0dcea8fa8c1dee8564b
4
- data.tar.gz: f6f4716e71b2505d0b0e1928679ba92bc572c4382bb165f4ae3a77de5c01abcb
3
+ metadata.gz: 137adc8bf19db9527fc5fdf3ec3eb5c71f0efd8b553d540eac1007a5ed31999a
4
+ data.tar.gz: '09d17f52234efab31318398e9bf4a2d992af47fee5c9870373dba1a7de20c13c'
5
5
  SHA512:
6
- metadata.gz: fbe56a69b398f32dfd2ba9ef1328fa3c10f6182f689b38089d8aa3a25e67130ee246459cf84e1b06e688172843b4b64c5aeaaec08fa9856fffd3ab5921625d59
7
- data.tar.gz: bd0b42b2043c0462914cfe240c59c931554b675001781642674bc82425c4c5df10aeb782acdcdaac4b1727e3e948bda9f93646455e5eaeb80ad91263239ee71f
6
+ metadata.gz: 257e7b406f1242637fb93b96da32a1ea7b08c189554d5442803b29dc8c182f13d9036d294ec62a2b65b0a25cad896e9203f5d9eb18fb0cea0d37245365250214
7
+ data.tar.gz: e84a120a6953ea3a08a8a1bd4a2c684923547f6fc83f357a1419d2832ad8c25e4fdbcd39cf4008fb88976db74020a1d007088f396391015ff20eeae2a23d72e2
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- swarm_cluster_cli_ope (0.4)
4
+ swarm_cluster_cli_ope (0.5.0.pre.3)
5
5
  activesupport
6
6
  open4
7
7
  thor (~> 1.0)
@@ -10,7 +10,7 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (6.0.3.3)
13
+ activesupport (6.0.3.4)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 0.7, < 2)
16
16
  minitest (~> 5.1)
@@ -24,9 +24,9 @@ GEM
24
24
  rake (12.3.3)
25
25
  thor (1.0.1)
26
26
  thread_safe (0.3.6)
27
- tzinfo (1.2.7)
27
+ tzinfo (1.2.8)
28
28
  thread_safe (~> 0.1)
29
- zeitwerk (2.4.0)
29
+ zeitwerk (2.4.1)
30
30
 
31
31
  PLATFORMS
32
32
  ruby
data/README.md CHANGED
@@ -110,7 +110,7 @@ ogni configurazione è composta da:
110
110
  }
111
111
  ```
112
112
 
113
- - service è il nome del servizio
113
+ - service è il nome del servizio (o nel caso di k8s una stringa da utilizzare come selettore labels)
114
114
  - how è il come sincronizzare, definendo la tipologia:
115
115
  - pg -> DB TODO
116
116
  - mysql -> DB: dump del db con mysqldump
@@ -193,7 +193,7 @@ Esempio di sincronizzazione di un file sqlite3 e una cartella
193
193
 
194
194
  nel file di configurazione creato nella home aggiungere la chiave "dev_mode":1 per collegarsi localmente
195
195
 
196
- ### Abbiamo due tasks swarm di simulazione
196
+ ### Abbiamo due tasks SWARM di simulazione
197
197
  ```shell script
198
198
  docker stack deploy -c test_folder/test_1/docker-compose.yml test_1_stack
199
199
  docker stack deploy -c test_folder/test_1/docker-compose.yml test1_staging
@@ -207,6 +207,11 @@ docker-compose -f test_folder/test_1/docker-compose-local.yml up -d
207
207
  ```
208
208
 
209
209
 
210
+ ### K8s
211
+ Per Kubernetes dobbiamo avere minikube installato.
212
+ lanciare quindi l'ambiente di test:
213
+
214
+ kubectl apply -f test_folder/test_k8s/test.yaml
210
215
 
211
216
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version
212
217
  number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git
@@ -0,0 +1,211 @@
1
+ module SwarmClusterCliOpe
2
+ ##
3
+ # Classe Base delle configurazioni, utilizzabile per swarm e kubernetes
4
+ class BaseConfiguration
5
+ include Singleton
6
+ include LoggerConcern
7
+
8
+ #@return [String] nome dello stack con cui lavoriamo
9
+ attr_accessor :stack_name
10
+
11
+ #@return [String] in che enviroment siamo, altrimenti siamo nel default
12
+ attr_accessor :environment
13
+
14
+ NoBaseConfigurations = Class.new(Error)
15
+
16
+ ##
17
+ # Serve per entrare nell'env corretto.
18
+ # passando l'env, tutto quello eseguito nello yield sarà gestito in quell'env.
19
+ # Verrà controllato quindi che esista il relativo file di configurazion
20
+ def env(enviroment = nil)
21
+ unless enviroment.nil?
22
+ @environment = enviroment.to_s.to_sym
23
+ end
24
+ logger.info { "ENV: #{@environment ? @environment : "BASE"}" }
25
+ yield self
26
+ @environment = nil
27
+ end
28
+
29
+ # @return [String,NilClass] nome dello stack del progetto se configurato
30
+ def stack_name
31
+ return nil unless self.class.exist_base?
32
+ @stack_name ||= Hash.new do |hash, key|
33
+ hash[key] = merged_configurations[:stack_name] if merged_configurations.key?(:stack_name)
34
+ end
35
+ @stack_name[environment]
36
+ end
37
+
38
+ ##
39
+ # Imposta il nome dello stack
40
+ def stack_name=(objs)
41
+ stack_name #lo richiamo per fargli generare la variabile di classe
42
+ @stack_name[environment] = objs
43
+ end
44
+
45
+ ##
46
+ # Livello di logging
47
+ # @return [Integer]
48
+ def logger_level
49
+ merged_configurations[:log_level].to_s || "0"
50
+ rescue SwarmClusterCliOpe::Configuration::NoBaseConfigurations
51
+ # quando andiamo in errore durante l'installazione per avere le informazioni per il logger.
52
+ # Usiamo lo standard
53
+ "0"
54
+ end
55
+
56
+ ##
57
+ # Siamo in sviluppo?
58
+ # @return [TrueClass, FalseClass]
59
+ def development_mode?
60
+ return false unless self.class.exist_base?
61
+ merged_configurations.key?(:dev_mode)
62
+ end
63
+
64
+ ##
65
+ # Controlla se esiste il file di configurazione base, nella home dell'utente
66
+ def self.exist_base?
67
+ File.exist?(base_cfg_path)
68
+ end
69
+
70
+
71
+ # @return [String] path to base home configurations
72
+ def self.base_cfg_path
73
+ File.join(ENV['HOME'], '.swarm_cluster', 'config.json')
74
+ end
75
+
76
+
77
+ ##
78
+ # Elenco di tutte le configurazioni di sincronizzazione
79
+ # @return [Array]
80
+ def sync_configurations
81
+ cfgs = merged_configurations[:sync_configs]
82
+ return [] if cfgs.nil? or !cfgs.is_a?(Array)
83
+ cfgs.collect do |c|
84
+
85
+ if self.get_syncro(c[:how])
86
+ self.get_syncro(c[:how]).new(self, c)
87
+ end
88
+
89
+ end.compact
90
+ end
91
+
92
+ ##
93
+ # Funzione per la restituzione della classe di sincro corretta
94
+ # @return [Class<SwarmClusterCliOpe::SyncConfigs::PostGres>, Class<SwarmClusterCliOpe::SyncConfigs::Mysql>, Class<SwarmClusterCliOpe::SyncConfigs::Rsync>, Class<SwarmClusterCliOpe::SyncConfigs::Sqlite3>, nil]
95
+ def get_syncro(name)
96
+ case name
97
+ when 'sqlite3'
98
+ SyncConfigs::Sqlite3
99
+ when 'rsync'
100
+ SyncConfigs::Rsync
101
+ when 'mysql'
102
+ SyncConfigs::Mysql
103
+ when 'pg'
104
+ SyncConfigs::PostGres
105
+ else
106
+ logger.error { "CONFIGURAIONE NON PREVISTA: #{name}" }
107
+ nil
108
+ end
109
+ end
110
+
111
+ ## Cerca le configurazioni di progetto e le mergia se sono presenti
112
+ # @return [Hash]
113
+ def merged_configurations
114
+ return @_merged_configurations[@environment] if @_merged_configurations
115
+
116
+ @_merged_configurations = Hash.new do |hash, key|
117
+ folder = FileUtils.pwd
118
+ default_file = looped_file(folder, self.class.cfgs_project_file_name)
119
+ enviroment_file = looped_file(folder, self.class.cfgs_project_file_name(with_env: key))
120
+
121
+ project_cfgs = {}
122
+ unless default_file.nil?
123
+ project_cfgs = JSON.parse(File.read(default_file)).deep_symbolize_keys
124
+ end
125
+
126
+ unless enviroment_file.nil?
127
+ project_cfgs.merge!(JSON.parse(File.read(enviroment_file)).deep_symbolize_keys)
128
+ end
129
+
130
+ hash[key] = self.class.read_base.merge(project_cfgs)
131
+ end
132
+
133
+ configuration_version = @_merged_configurations[@environment][:version]
134
+ if Gem::Version.new(configuration_version) > Gem::Version.new(VERSION)
135
+ puts "WARNING: Versione del file di configurazione [#{configuration_version}] più aggiornata della gemma [#{VERSION}], eseguire upgrade
136
+ gem update swarm_cluster_cli_ope"
137
+ exit
138
+ end
139
+
140
+ @_merged_configurations[@environment]
141
+
142
+ end
143
+
144
+
145
+ ##
146
+ # Si occupa del salvataggio delle configurazioni di progetto, se abbiamo lo stack_name
147
+ def save_project_cfgs
148
+ if stack_name
149
+ File.open(File.join(FileUtils.pwd, self.class.cfgs_project_file_name(with_env: @environment)), "wb") do |f|
150
+ f.write({
151
+ stack_name: stack_name,
152
+ version: VERSION
153
+ }.to_json)
154
+ end
155
+ end
156
+ end
157
+
158
+
159
+ ##
160
+ # Salva le configurazioni base in HOME
161
+ def save_base_cfgs
162
+ FileUtils.mkdir_p(File.dirname(self.class.base_cfg_path))
163
+ File.open(self.class.base_cfg_path, "wb") do |f|
164
+ obj= {
165
+ version: SwarmClusterCliOpe::VERSION,
166
+ }
167
+ obj = yield(obj) if block_given?
168
+
169
+ f.write(obj.to_json)
170
+ end
171
+ end
172
+
173
+
174
+
175
+ private
176
+ ##
177
+ # nome del file in cui salvare le configurazioni di progetto
178
+ # @return [String]
179
+ # @param [nil|String] with_env nome dell'env da cercare
180
+ def self.cfgs_project_file_name(with_env: nil)
181
+ ".swarm_cluster_project#{with_env ? ".#{with_env}" : ""}"
182
+ end
183
+
184
+ ##
185
+ # Legge le configurazioni base
186
+ #
187
+ # @return [Hash]
188
+ def self.read_base
189
+ raise NoBaseConfigurations if !exist_base? or File.size(self.base_cfg_path)==0
190
+ JSON.parse(File.read(self.base_cfg_path)).deep_symbolize_keys
191
+ end
192
+
193
+ def looped_file(start_folder, file)
194
+ project_file = nil
195
+ loop do
196
+
197
+ if File.exist?(File.join(start_folder, file))
198
+ project_file = File.join(start_folder, file)
199
+ end
200
+
201
+ break unless project_file.nil?
202
+ break if start_folder == '/'
203
+ start_folder = File.expand_path("..", start_folder)
204
+ end
205
+
206
+ project_file
207
+ end
208
+
209
+
210
+ end
211
+ end
@@ -5,6 +5,7 @@ module SwarmClusterCliOpe
5
5
  class Cli < Thor
6
6
  include LoggerConcern
7
7
  include ConfigurationConcern
8
+ include ThorConfigurationConcern
8
9
  include Thor::Actions
9
10
 
10
11
  def self.exit_on_failure?
@@ -14,6 +15,10 @@ module SwarmClusterCliOpe
14
15
  class_option :environment, required: false, type: :string, aliases: [:e],
15
16
  desc: "Esegue tutte le operazioni nell'env scelto, il file di configurazione dovrà avere il nome: #{Configuration.cfgs_project_file_name}.ENV"
16
17
 
18
+
19
+ desc "k8s SUBCOMMAND ...ARGS", "Gestisce un set di comandi specifici per K8s"
20
+ subcommand "k8s", K8s
21
+
17
22
  desc "install", "Creazione della configurazione base della gemma"
18
23
 
19
24
  def install
@@ -40,14 +45,6 @@ module SwarmClusterCliOpe
40
45
 
41
46
  end
42
47
 
43
- desc "config", "Visualizza le configurazioni mergiate (HOME + Project configuration[#{Configuration.cfgs_project_file_name}])"
44
-
45
- def config
46
- cfgs.env(options[:environment]) do
47
- puts JSON.pretty_generate(cfgs.merged_configurations)
48
- end
49
- end
50
-
51
48
 
52
49
  # DOCKER_HOST=ssh://swarm_node_1 docker stack ls --format="{{json .}}"
53
50
  desc "stacks", "Lista degli stacks nel cluster"
@@ -187,16 +184,6 @@ module SwarmClusterCliOpe
187
184
  end
188
185
 
189
186
 
190
- desc "configure_project STACK_NAME", "Genera il file di configurazione del progetto contenente il nome dello stack"
191
-
192
- def configure_project(stack_name)
193
- cfgs.env(options[:environment]) do |c|
194
- c.stack_name = stack_name
195
- c.save_project_cfgs
196
- end
197
- end
198
-
199
-
200
187
  desc "service_shell SERVICE_NAME", "apre una shell [default bash] dentro al container"
201
188
  option :stack_name, required: false, type: :string
202
189
  option :shell, required: false, type: :string, default: 'bash'
@@ -248,117 +235,7 @@ module SwarmClusterCliOpe
248
235
  say VERSION
249
236
  end
250
237
 
251
- desc "stacksync [DIRECTION:pull|push]", "Si occupa di scaricare|caricare,utilizzando le configurazioni presenti, i dati dallo stack remoto"
252
- long_desc <<-LONGDESC.gsub("\n", "\x5")
253
- le configurazioni sono contenute nell'array: sync_configs.
254
- ogni configurazione è composta da:
255
- {
256
- service:""
257
- how:""
258
- configs:{ }
259
- }
260
- - service è il nome del servizio
261
- - how è il come sincronizzare, definendo la tipologia:
262
- ---- pg -> DB TODO
263
- ---- mysql -> DB dump con mysql
264
- ---- sqlite3 -> DB: viene eseguita una copia del file
265
- ---- rsync -> RSYNC
266
- - configs: è un hash con le configurazioni per ogni tipo di sincronizzazione
267
-
268
- Possibili CFGS per tipologia:
269
- rsync:
270
- --local: -> path cartella locale
271
- --remote: -> path cartella remota (contesto del container)
272
-
273
- sqlite3:
274
- --local: -> path al file
275
- --remote: -> path al file remoto (contesto del container)
276
-
277
- mysql:
278
- --local: -> hash di configurazioni per il DB locale
279
- - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
280
- - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
281
- - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
282
- - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
283
- - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
284
- - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
285
- - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
286
- --remote: -> hash di configurazioni per il DB remoto
287
- - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
288
- - mysql_password_env: "MYSQL_PASSWORD" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: MYSQL_PASSWORD
289
- - mysql_password: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
290
- - mysql_user_env: "MYSQL_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: MYSQL_USER
291
- - mysql_user: "root" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: root
292
- - database_name_env: "MYSQL_DATABASE" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: MYSQL_DATABASE
293
- - database_name: "MYSQL_DATABASE" -> valore in chiaro, in sostituzione della variabile ambiente
294
- pg:
295
- --local: -> hash di configurazioni per il DB locale
296
- - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
297
- - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
298
- - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
299
- - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
300
- - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
301
- - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
302
- - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
303
- --remote: -> hash di configurazioni per il DB remoto
304
- - service: "db" -> nome del servizio nel compose locale, DEFAULT: quello definito sopra
305
- - pg_password_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente PASSWORD, DEFAULT: POSTGRES_PASSWORD
306
- - pg_password: "" -> valore in chiaro, in sostituzione della variabile ambiente
307
- - pg_user_env: "POSTGRES_USER" -> variabile ambiente interna al servizio contenente USERNAME, DEFAULT: POSTGRES_USER
308
- - pg_user: "postgres" -> valore in chiaro, in sostituzione della variabile ambiente, DEFAULT: postgres
309
- - database_name_env: "POSTGRES_DB" -> variabile ambiente interna al servizio contenente NOME DB, DEFAULT: POSTGRES_DB
310
- - database_name: "nome_db" -> valore in chiaro, in sostituzione della variabile ambiente
311
-
312
-
313
- EXAMPLE:
314
- Esempio di sincronizzazione di un file sqlite3 e una cartella
315
- {
316
- "stack_name": "test1",
317
- "sync_configs": [
318
- {
319
- "service": "second",
320
- "how": "rsync",
321
- "configs": {
322
- "remote": "/test_bind",
323
- "local": "./uploads"
324
- }
325
- },
326
- {
327
- "service": "test_sqlite3",
328
- "how": "sqlite3",
329
- "configs": {
330
- "remote": "/cartella_sqlite3/esempio.sqlite3",
331
- "local": "./development.sqlite3"
332
- }
333
- }
334
- ]
335
- }
336
- LONGDESC
337
-
338
- def stacksync(direction)
339
- direction = case direction
340
- when 'push'
341
- :push
342
- when 'pull'
343
- :pull
344
- else
345
- raise "ONLY [push|pull] action accepted"
346
- end
347
- cfgs.env(options[:environment]) do |cfgs|
348
- sync_cfgs = cfgs.sync_configurations
349
- if sync_cfgs.empty?
350
- say "Attenzione, configurazioni di sincronizzazione vuoto. Leggere la documentazione"
351
- else
352
- sync_cfgs.each do |sync|
353
- say "----------->>>>>>"
354
- say "[ #{sync.class.name} ]"
355
- sync.send(direction)
356
- say "COMPLETE"
357
- say "<<<<<<-----------"
358
- end
359
- end
360
- end
361
- end
238
+ include StackSyncConcern
362
239
 
363
240
  private
364
241