caco 0.1.0

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.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +10 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/Gemfile +12 -0
  6. data/Gemfile.lock +227 -0
  7. data/Guardfile +42 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +97 -0
  10. data/Rakefile +10 -0
  11. data/bin/_guard-core +29 -0
  12. data/bin/bundle +114 -0
  13. data/bin/byebug +29 -0
  14. data/bin/caco +29 -0
  15. data/bin/coderay +29 -0
  16. data/bin/console +20 -0
  17. data/bin/eyaml +29 -0
  18. data/bin/guard +29 -0
  19. data/bin/listen +29 -0
  20. data/bin/pry +29 -0
  21. data/bin/rake +29 -0
  22. data/bin/safe_yaml +29 -0
  23. data/bin/setup +8 -0
  24. data/bin/thor +29 -0
  25. data/bin/tilt +29 -0
  26. data/caco.gemspec +43 -0
  27. data/exe/caco +27 -0
  28. data/lib/caco.rb +115 -0
  29. data/lib/caco/barman.rb +10 -0
  30. data/lib/caco/barman/cell/global.rb +4 -0
  31. data/lib/caco/barman/cell/node.rb +15 -0
  32. data/lib/caco/barman/install.rb +25 -0
  33. data/lib/caco/barman/view/global.erb +7 -0
  34. data/lib/caco/barman/view/node.erb +8 -0
  35. data/lib/caco/cell.rb +8 -0
  36. data/lib/caco/config.rb +23 -0
  37. data/lib/caco/debian.rb +28 -0
  38. data/lib/caco/debian/add_user.rb +18 -0
  39. data/lib/caco/debian/apt_key_install.rb +19 -0
  40. data/lib/caco/debian/apt_repo_add.rb +17 -0
  41. data/lib/caco/debian/apt_sources_list.rb +15 -0
  42. data/lib/caco/debian/apt_update.rb +33 -0
  43. data/lib/caco/debian/cell/service.rb +19 -0
  44. data/lib/caco/debian/cell/sources_list.rb +7 -0
  45. data/lib/caco/debian/package_install.rb +21 -0
  46. data/lib/caco/debian/package_installed.rb +17 -0
  47. data/lib/caco/debian/service_enable.rb +26 -0
  48. data/lib/caco/debian/service_install.rb +31 -0
  49. data/lib/caco/debian/user_home.rb +17 -0
  50. data/lib/caco/debian/view/service.erb +18 -0
  51. data/lib/caco/debian/view/sources_list.erb +10 -0
  52. data/lib/caco/downloader.rb +41 -0
  53. data/lib/caco/executer.rb +33 -0
  54. data/lib/caco/facter.rb +41 -0
  55. data/lib/caco/file_link.rb +36 -0
  56. data/lib/caco/file_reader.rb +24 -0
  57. data/lib/caco/file_writer.rb +57 -0
  58. data/lib/caco/finder.rb +13 -0
  59. data/lib/caco/grafana.rb +6 -0
  60. data/lib/caco/grafana/install.rb +26 -0
  61. data/lib/caco/haproxy.rb +12 -0
  62. data/lib/caco/haproxy/cell/conf_postgres.rb +4 -0
  63. data/lib/caco/haproxy/cell/conf_stats.rb +4 -0
  64. data/lib/caco/haproxy/conf_get.rb +15 -0
  65. data/lib/caco/haproxy/conf_set.rb +52 -0
  66. data/lib/caco/haproxy/install.rb +9 -0
  67. data/lib/caco/haproxy/view/conf_postgres.erb +25 -0
  68. data/lib/caco/haproxy/view/conf_stats.erb +6 -0
  69. data/lib/caco/macro.rb +2 -0
  70. data/lib/caco/postgres.rb +44 -0
  71. data/lib/caco/postgres/build_augeas.rb +20 -0
  72. data/lib/caco/postgres/conf_get.rb +37 -0
  73. data/lib/caco/postgres/conf_set.rb +54 -0
  74. data/lib/caco/postgres/database_create.rb +28 -0
  75. data/lib/caco/postgres/extension_create.rb +28 -0
  76. data/lib/caco/postgres/hba_set.rb +65 -0
  77. data/lib/caco/postgres/install.rb +34 -0
  78. data/lib/caco/postgres/shell.rb +13 -0
  79. data/lib/caco/postgres/sql.rb +17 -0
  80. data/lib/caco/postgres/user_change_password.rb +13 -0
  81. data/lib/caco/postgres/user_create.rb +33 -0
  82. data/lib/caco/prometheus.rb +15 -0
  83. data/lib/caco/prometheus/adapter_install_pg.rb +107 -0
  84. data/lib/caco/prometheus/adapter_install_postgresql.rb +47 -0
  85. data/lib/caco/prometheus/cell/alertmanager_conf.rb +4 -0
  86. data/lib/caco/prometheus/cell/alerts.rb +4 -0
  87. data/lib/caco/prometheus/cell/conf.rb +7 -0
  88. data/lib/caco/prometheus/exporter_install.rb +35 -0
  89. data/lib/caco/prometheus/install.rb +50 -0
  90. data/lib/caco/prometheus/install_alert_manager.rb +62 -0
  91. data/lib/caco/prometheus/view/alertmanager_conf.erb +13 -0
  92. data/lib/caco/prometheus/view/alerts.erb +18 -0
  93. data/lib/caco/prometheus/view/conf.erb +34 -0
  94. data/lib/caco/rbenv.rb +8 -0
  95. data/lib/caco/rbenv/cell/profile.rb +4 -0
  96. data/lib/caco/rbenv/install.rb +56 -0
  97. data/lib/caco/rbenv/install_version.rb +17 -0
  98. data/lib/caco/rbenv/view/profile.erb +3 -0
  99. data/lib/caco/repmgr.rb +15 -0
  100. data/lib/caco/repmgr/cell/conf.rb +43 -0
  101. data/lib/caco/repmgr/conf.rb +25 -0
  102. data/lib/caco/repmgr/install.rb +25 -0
  103. data/lib/caco/repmgr/node_register_primary.rb +34 -0
  104. data/lib/caco/repmgr/node_register_standby.rb +25 -0
  105. data/lib/caco/repmgr/node_registered.rb +15 -0
  106. data/lib/caco/repmgr/node_role.rb +18 -0
  107. data/lib/caco/repmgr/view/conf.erb +27 -0
  108. data/lib/caco/settings_loader.rb +67 -0
  109. data/lib/caco/settings_loader_monkeypatch.rb +28 -0
  110. data/lib/caco/ssh.rb +6 -0
  111. data/lib/caco/ssh/authorized_keys_add.rb +82 -0
  112. data/lib/caco/sudo.rb +6 -0
  113. data/lib/caco/sudo/sudoers_add.rb +15 -0
  114. data/lib/caco/timescale.rb +6 -0
  115. data/lib/caco/timescale/install.rb +25 -0
  116. data/lib/caco/unpacker.rb +76 -0
  117. data/lib/caco/version.rb +3 -0
  118. metadata +398 -0
@@ -0,0 +1,13 @@
1
+ module Caco
2
+ class Finder < Trailblazer::Operation
3
+ step Subprocess(Caco::Executer),
4
+ input: [:command],
5
+ output: { exit_code: :command_exit_code, output: :command_output },
6
+ id: "execute_command"
7
+
8
+ step ->(ctx, command_output:, regexp:, **) {
9
+ command_output.freeze.match?(regexp)
10
+ },
11
+ id: :match_regexp
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ module Caco
2
+ module Grafana
3
+ end
4
+ end
5
+
6
+ require 'caco/grafana/install'
@@ -0,0 +1,26 @@
1
+ module Caco::Grafana
2
+ class Install < Trailblazer::Operation
3
+ class Repo < Trailblazer::Operation
4
+ step Subprocess(Caco::Debian::AptKeyInstall),
5
+ input: ->(_ctx, **) {{
6
+ url: 'https://packages.grafana.com/gpg.key',
7
+ fingerprint: '4E40 DDF6 D76E 284A 4A67 80E4 8C8C 34C5 2409 8CB6'
8
+ }}
9
+
10
+ step Subprocess(Caco::Debian::AptRepoAdd),
11
+ input: ->(_ctx, **) {{
12
+ name: 'grafana',
13
+ url: 'https://packages.grafana.com/oss/deb',
14
+ release: "stable",
15
+ component: 'main'
16
+ }}
17
+ end
18
+
19
+ step Subprocess(Repo)
20
+ step Subprocess(Caco::Debian::AptUpdate)
21
+ step Subprocess(Caco::Debian::PackageInstall),
22
+ input: ->(_ctx, **) {{
23
+ package: 'grafana'
24
+ }}
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ module Caco
2
+ module Haproxy
3
+ end
4
+ end
5
+
6
+ require 'caco/haproxy/conf_get'
7
+ require 'caco/haproxy/conf_set'
8
+ require 'caco/haproxy/install'
9
+
10
+ # Templates
11
+ require 'caco/haproxy/cell/conf_postgres'
12
+ require 'caco/haproxy/cell/conf_stats'
@@ -0,0 +1,4 @@
1
+ module Caco::Haproxy::Cell
2
+ class ConfPostgres < Trailblazer::Cell
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Caco::Haproxy::Cell
2
+ class ConfStats < Trailblazer::Cell
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ class Caco::Haproxy::ConfGet < Trailblazer::Operation
2
+ step Subprocess(Caco::FileReader),
3
+ input: ->(_ctx, **) {{
4
+ path: "/etc/default/haproxy",
5
+ }},
6
+ output: [:output]
7
+
8
+ step ->(ctx, name:, output:, **) {
9
+ match = output.match(/^#{name}=\"(.*)\"/)
10
+ return false unless match
11
+
12
+ ctx[:value] = match[1]
13
+ },
14
+ id: :find_value
15
+ end
@@ -0,0 +1,52 @@
1
+ class Caco::Haproxy::ConfSet < Trailblazer::Operation
2
+ step Subprocess(Caco::FileReader),
3
+ input: ->(_ctx, **) {{
4
+ path: "/etc/default/haproxy",
5
+ }},
6
+ output: [:output]
7
+
8
+ step Subprocess(Caco::Haproxy::ConfGet),
9
+ input: ->(_ctx, name:, **) {{
10
+ name: name,
11
+ }},
12
+ output: {value: :existing_value}
13
+
14
+ step :change_value
15
+
16
+ fail :create_value, Output(:success) => Track(:success)
17
+
18
+ step :check_values_are_the_same,
19
+ Output(:success) => End(:success),
20
+ Output(:failure) => Track(:success)
21
+
22
+ step Subprocess(Caco::FileWriter),
23
+ input: ->(_ctx, new_config_content:, **) {{
24
+ path: "/etc/default/haproxy",
25
+ content: new_config_content
26
+ }}
27
+
28
+ def change_value(ctx, output:, name:, value:, **)
29
+ ctx[:created] = false
30
+ ctx[:changed] = true
31
+ ctx[:new_config_content] = output.gsub!(/^#{name}=\"(.*)\"/, "#{name}=\"#{value}\"")
32
+ true
33
+ end
34
+
35
+ def create_value(ctx, output:, name:, value:, **)
36
+ ctx[:created] = true
37
+ ctx[:changed] = true
38
+ output << "#{name}=\"#{value}\"\n"
39
+ ctx[:new_config_content] = output
40
+ true
41
+ end
42
+
43
+ def check_values_are_the_same(ctx, value:, existing_value:, **)
44
+ if value == existing_value
45
+ ctx[:changed] = nil
46
+ ctx[:created] = nil
47
+ true
48
+ else
49
+ false
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ module Caco::Haproxy
2
+ class Install < Trailblazer::Operation
3
+ step Subprocess(Caco::Debian::AptUpdate)
4
+ step Subprocess(Caco::Debian::PackageInstall),
5
+ input: ->(_ctx, **) {{
6
+ package: 'haproxy'
7
+ }}
8
+ end
9
+ end
@@ -0,0 +1,25 @@
1
+ listen haproxy_10.0.0.30_3307_rw
2
+ bind *:3307
3
+ mode tcp
4
+ timeout client 10800s
5
+ timeout server 10800s
6
+ tcp-check expect string primary\ is\ running
7
+ balance leastconn
8
+ option tcp-check
9
+ option allbackups
10
+ default-server port 9300 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
11
+ server 10.0.0.21 10.0.0.21:5432 check
12
+ server 10.0.0.22 10.0.0.22:5432 check
13
+
14
+ listen haproxy_10.0.0.30_3308_ro
15
+ bind *:3308
16
+ mode tcp
17
+ timeout client 10800s
18
+ timeout server 10800s
19
+ tcp-check expect string is\ running.
20
+ balance leastconn
21
+ option tcp-check
22
+ option allbackups
23
+ default-server port 9300 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
24
+ server 10.0.0.21 10.0.0.21:5432 check
25
+ server 10.0.0.22 10.0.0.22:5432 check
@@ -0,0 +1,6 @@
1
+ frontend stats
2
+ bind *:8404
3
+ stats enable
4
+ stats uri /stats
5
+ stats refresh 10s
6
+ stats admin if LOCALHOST
@@ -0,0 +1,2 @@
1
+ module Caco::Macro
2
+ end
@@ -0,0 +1,44 @@
1
+ module Caco
2
+ module Postgres
3
+ module ClassMethods
4
+ def add_shared_library(lib)
5
+ @libraries ||= []
6
+ @libraries << lib
7
+ true
8
+ end
9
+
10
+ def shared_libraries
11
+ @libraries ||= []
12
+ @libraries.join(", ")
13
+ end
14
+
15
+ def clear_shared_library
16
+ @libraries = []
17
+ end
18
+
19
+ def should_restart!
20
+ @should_restart = true
21
+ end
22
+
23
+ def should_restart?
24
+ @should_restart || false
25
+ end
26
+ end
27
+
28
+ extend ClassMethods
29
+ end
30
+ end
31
+
32
+ require 'caco/postgres/build_augeas'
33
+ require 'caco/postgres/conf_get'
34
+ require 'caco/postgres/conf_set'
35
+ require 'caco/postgres/hba_set'
36
+ require 'caco/postgres/install'
37
+ require 'caco/postgres/shell'
38
+ require 'caco/postgres/sql'
39
+
40
+ # depends on sql
41
+ require 'caco/postgres/database_create'
42
+ require 'caco/postgres/extension_create'
43
+ require 'caco/postgres/user_change_password'
44
+ require 'caco/postgres/user_create'
@@ -0,0 +1,20 @@
1
+ module Caco::Postgres
2
+ def self.BuildAugeas
3
+ task = ->((ctx, flow_options), _) do
4
+ augeas_path = ctx[:augeas_path] ? ctx[:augeas_path] : "/"
5
+
6
+ ctx[:aug] = aug = Augeas::open(augeas_path, nil, Augeas::NO_LOAD)
7
+ aug.clear_transforms
8
+ aug.transform(:lens => "Postgresql.lns", :incl => "/postgresql.conf")
9
+ aug.load
10
+
11
+ return Trailblazer::Activity::Right, [ctx, flow_options]
12
+ end
13
+
14
+ # new API
15
+ {
16
+ task: task,
17
+ id: "build_augeas"
18
+ }
19
+ end
20
+ end
@@ -0,0 +1,37 @@
1
+ module Caco::Postgres
2
+ class ConfGet < Trailblazer::Operation
3
+ ProcessSingleValue = Class.new(Trailblazer::Activity::Signal)
4
+ ProcessMultipleValue = Class.new(Trailblazer::Activity::Signal)
5
+
6
+ step Caco::Postgres::BuildAugeas()
7
+
8
+ step :define_what_process,
9
+ Output(ProcessSingleValue, :single_value) => Id(:process_single_value),
10
+ Output(ProcessMultipleValue, :multiple_values) => Id(:process_multiple_values),
11
+ Output(Trailblazer::Activity::Left, :failure) => End(:failure)
12
+
13
+ step :process_single_value, magnetic_to: nil
14
+ step :process_multiple_values, magnetic_to: nil
15
+
16
+ def define_what_process(ctx, name: nil, names: nil, **)
17
+ if name and name.is_a?(String)
18
+ return ProcessSingleValue
19
+ elsif names and names.is_a?(Array)
20
+ return ProcessMultipleValue
21
+ else
22
+ return false
23
+ end
24
+ end
25
+
26
+ def process_single_value(ctx, name:, aug:, **)
27
+ ctx[:value] = aug.get("/files/postgresql.conf/#{name}")
28
+ end
29
+
30
+ def process_multiple_values(ctx, names:, aug:, **)
31
+ ctx[:values] = {}
32
+ names.each do |name|
33
+ ctx[:values][name.to_s] = aug.get("/files/postgresql.conf/#{name}")
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,54 @@
1
+ module Caco::Postgres
2
+ class ConfSet < Trailblazer::Operation
3
+ ProcessSingleValue = Class.new(Trailblazer::Activity::Signal)
4
+ ProcessMultipleValue = Class.new(Trailblazer::Activity::Signal)
5
+
6
+ step Caco::Postgres::BuildAugeas()
7
+
8
+ step :define_what_process,
9
+ Output(ProcessSingleValue, :single_value) => Id(:process_single_value),
10
+ Output(ProcessMultipleValue, :multiple_values) => Id(:process_multiple_values),
11
+ Output(Trailblazer::Activity::Left, :failure) => End(:failure)
12
+ step :process_single_value, magnetic_to: nil
13
+ step :process_multiple_values, magnetic_to: nil
14
+
15
+ def define_what_process(ctx, name: nil, names: nil, value: nil, values: nil, **)
16
+ if name && value
17
+ return ProcessSingleValue
18
+ elsif values and values.is_a?(Hash)
19
+ return ProcessMultipleValue
20
+ else
21
+ return false
22
+ end
23
+ end
24
+
25
+ def process_single_value(ctx, name:, value:, aug:, **)
26
+ ctx[:existing_value] = aug.get("/files/postgresql.conf/#{name}")
27
+ ctx[:created] = !ctx[:existing_value]
28
+ if ctx[:existing_value] == value
29
+ return true
30
+ else
31
+ ctx[:changed] = true
32
+ ctx[:value] = aug.set("/files/postgresql.conf/#{name}", value)
33
+ aug.save!
34
+ end
35
+ true
36
+ end
37
+
38
+ def process_multiple_values(ctx, values:, aug:, **)
39
+ ctx[:values] = {}
40
+ values.each_pair do |name, value|
41
+ ctx[:existing_value] = aug.get("/files/postgresql.conf/#{name}")
42
+ ctx[:created] = true unless ctx[:existing_value]
43
+ if ctx[:existing_value] == value
44
+ next
45
+ else
46
+ ctx[:changed] = true
47
+ ctx[:values][name.to_s] = aug.set("/files/postgresql.conf/#{name}", value)
48
+ end
49
+ end
50
+ aug.save! if ctx[:changed]
51
+ true
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,28 @@
1
+ module Caco::Postgres
2
+ class DatabaseCreate < Trailblazer::Operation
3
+
4
+ step Subprocess(Caco::Postgres::Sql),
5
+ input: ->(_ctx, database:, **) {{
6
+ sql: "select datname from pg_database where datname='#{database}';",
7
+ }},
8
+ id: :sql_find_database
9
+
10
+ step ->(_ctx, output:, database:, **) {
11
+ output.match?(/^\s#{database}$/)
12
+ },
13
+ Output(:success) => End(:success),
14
+ Output(:failure) => Track(:success),
15
+ id: :verify_database_exists
16
+
17
+ step Subprocess(Caco::Executer),
18
+ input: ->(ctx, database:, **) {{
19
+ command: "createdb -e #{ctx[:additional_args]} #{database}",
20
+ }},
21
+ id: :create_database
22
+
23
+ step ->(ctx, **) {
24
+ ctx[:created] = ctx[:changed] = true
25
+ },
26
+ id: :mark_created
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ module Caco::Postgres
2
+ class ExtensionCreate < Trailblazer::Operation
3
+
4
+ step Subprocess(Caco::Postgres::Sql),
5
+ input: ->(_ctx, extension:, **) {{
6
+ sql: "select extname from pg_extension where extname='#{extension}';",
7
+ }},
8
+ id: :sql_find_extension
9
+
10
+ step ->(_ctx, output:, extension:, **) {
11
+ output.match?(/^\s#{extension}$/)
12
+ },
13
+ Output(:success) => End(:success),
14
+ Output(:failure) => Track(:success),
15
+ id: :verify_extension_exists
16
+
17
+ step Subprocess(Class.new(Caco::Postgres::Sql)),
18
+ input: ->(_ctx, extension:, **) {{
19
+ sql: "create extension #{extension};",
20
+ }},
21
+ id: :create_extension
22
+
23
+ step ->(ctx, **) {
24
+ ctx[:created] = ctx[:changed] = true
25
+ },
26
+ id: :mark_created
27
+ end
28
+ end
@@ -0,0 +1,65 @@
1
+ class Caco::Postgres::HbaSet < Trailblazer::Operation
2
+ class InvalidType < StandardError; end
3
+ class InvalidMethod < StandardError; end
4
+ class MissingNetworkValue < StandardError; end
5
+ ValidTypes = %w( local host hostssl hostnossl )
6
+ ValidMethods = %w( trust reject md5 password scram-sha-256 gss sspi ident peer pam ldap radius or cert )
7
+
8
+ TypeLocal = Class.new(Trailblazer::Activity::Signal)
9
+ TypeHost = Class.new(Trailblazer::Activity::Signal)
10
+
11
+ step :check_type_is_valid
12
+ step :check_method_is_valid
13
+ step :check_value_exist,
14
+ Output(:success) => End(:success),
15
+ Output(:failure) => Track(:success)
16
+ step :check_if_network_value_is_needed
17
+ step :append_value
18
+ step ->(ctx, **) {
19
+ ctx[:created] = ctx[:changed] = true
20
+ },
21
+ id: :mark_as_changed
22
+
23
+ def check_type_is_valid(ctx, type:, **)
24
+ raise InvalidType.new("`#{type}' is not a valid type") unless ValidTypes.include?(type)
25
+ true
26
+ end
27
+
28
+ def check_method_is_valid(ctx, method:, **)
29
+ raise InvalidMethod.new("`#{method}' is not a valid method") unless ValidMethods.include?(method)
30
+ true
31
+ end
32
+
33
+ def check_value_exist(ctx, input:, type:, database:, user:, method:, **)
34
+ return input.match?(/^#{type}\s+#{database}\s+#{user}\s+#{method}$/) if type == 'local'
35
+ input.match?(/^#{type}\s+#{database}\s+#{user}\s+#{ctx[:network]}\s+#{method}$/)
36
+ end
37
+
38
+ def check_if_network_value_is_needed(ctx, type:, **)
39
+ return true if type == 'local'
40
+ return true if ctx[:network]
41
+ raise MissingNetworkValue.new("You need to enter a value for network when #{type} is specified")
42
+ end
43
+
44
+ def append_value(ctx, input:, type:, database:, user:, method:, **)
45
+ after_type_size = 8 - type.size > 0 ? (8 - type.size) : 1
46
+ after_type_spaces = " " * after_type_size
47
+
48
+ after_db_size = 16 - database.size > 0 ? (16 - database.size) : 1
49
+ after_db_spaces = " " * after_db_size
50
+
51
+ after_user_size = 16 - user.size > 0 ? (16 - user.size) : 1
52
+ after_user_spaces = " " * after_user_size
53
+
54
+ network_size = ctx[:network].size rescue 0
55
+ after_network_size = 24 - network_size > 0 ? 24 - network_size : 1
56
+ after_network_spaces = " " * after_network_size
57
+
58
+ if type == 'local'
59
+ input << "#{type}#{after_type_spaces}#{database}#{after_db_spaces}#{user}#{after_user_spaces}#{after_network_spaces}#{method}\n"
60
+ else
61
+ input << "#{type}#{after_type_spaces}#{database}#{after_db_spaces}#{user}#{after_user_spaces}#{ctx[:network]}#{after_network_spaces}#{method}\n"
62
+ end
63
+ ctx[:content] = input
64
+ end
65
+ end