simplygenius-atmos 0.7.1 → 0.8.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/exe/atmos +2 -2
  4. data/lib/{atmos.rb → simplygenius/atmos.rb} +9 -7
  5. data/lib/simplygenius/atmos/cli.rb +116 -0
  6. data/lib/simplygenius/atmos/commands/account.rb +69 -0
  7. data/lib/simplygenius/atmos/commands/apply.rb +24 -0
  8. data/lib/simplygenius/atmos/commands/auth_exec.rb +34 -0
  9. data/lib/simplygenius/atmos/commands/base_command.rb +16 -0
  10. data/lib/simplygenius/atmos/commands/bootstrap.rb +76 -0
  11. data/lib/simplygenius/atmos/commands/container.rb +62 -0
  12. data/lib/simplygenius/atmos/commands/destroy.rb +22 -0
  13. data/lib/simplygenius/atmos/commands/generate.rb +187 -0
  14. data/lib/simplygenius/atmos/commands/init.rb +22 -0
  15. data/lib/simplygenius/atmos/commands/new.rb +22 -0
  16. data/lib/simplygenius/atmos/commands/otp.rb +58 -0
  17. data/lib/simplygenius/atmos/commands/plan.rb +24 -0
  18. data/lib/simplygenius/atmos/commands/secret.rb +91 -0
  19. data/lib/simplygenius/atmos/commands/terraform.rb +56 -0
  20. data/lib/simplygenius/atmos/commands/user.rb +78 -0
  21. data/lib/simplygenius/atmos/config.rb +279 -0
  22. data/lib/simplygenius/atmos/exceptions.rb +13 -0
  23. data/lib/simplygenius/atmos/generator.rb +232 -0
  24. data/lib/simplygenius/atmos/ipc.rb +136 -0
  25. data/lib/simplygenius/atmos/ipc_actions/notify.rb +31 -0
  26. data/lib/simplygenius/atmos/ipc_actions/ping.rb +23 -0
  27. data/lib/simplygenius/atmos/logging.rb +164 -0
  28. data/lib/simplygenius/atmos/otp.rb +62 -0
  29. data/lib/simplygenius/atmos/plugin.rb +27 -0
  30. data/lib/simplygenius/atmos/plugin_manager.rb +120 -0
  31. data/lib/simplygenius/atmos/plugins/output_filter.rb +29 -0
  32. data/lib/simplygenius/atmos/plugins/prompt_notify.rb +21 -0
  33. data/lib/simplygenius/atmos/provider_factory.rb +23 -0
  34. data/lib/simplygenius/atmos/providers/aws/account_manager.rb +83 -0
  35. data/lib/simplygenius/atmos/providers/aws/auth_manager.rb +220 -0
  36. data/lib/simplygenius/atmos/providers/aws/container_manager.rb +118 -0
  37. data/lib/simplygenius/atmos/providers/aws/provider.rb +53 -0
  38. data/lib/simplygenius/atmos/providers/aws/s3_secret_manager.rb +51 -0
  39. data/lib/simplygenius/atmos/providers/aws/user_manager.rb +213 -0
  40. data/lib/simplygenius/atmos/settings_hash.rb +93 -0
  41. data/lib/simplygenius/atmos/source_path.rb +186 -0
  42. data/lib/simplygenius/atmos/template.rb +117 -0
  43. data/lib/simplygenius/atmos/terraform_executor.rb +297 -0
  44. data/lib/simplygenius/atmos/ui.rb +173 -0
  45. data/lib/simplygenius/atmos/utils.rb +54 -0
  46. data/lib/simplygenius/atmos/version.rb +5 -0
  47. data/templates/new/config/atmos.yml +21 -13
  48. data/templates/new/config/atmos/recipes.yml +16 -0
  49. data/templates/new/config/atmos/runtime.yml +9 -0
  50. metadata +46 -40
  51. data/lib/atmos/cli.rb +0 -105
  52. data/lib/atmos/commands/account.rb +0 -65
  53. data/lib/atmos/commands/apply.rb +0 -20
  54. data/lib/atmos/commands/auth_exec.rb +0 -29
  55. data/lib/atmos/commands/base_command.rb +0 -12
  56. data/lib/atmos/commands/bootstrap.rb +0 -72
  57. data/lib/atmos/commands/container.rb +0 -58
  58. data/lib/atmos/commands/destroy.rb +0 -18
  59. data/lib/atmos/commands/generate.rb +0 -90
  60. data/lib/atmos/commands/init.rb +0 -18
  61. data/lib/atmos/commands/new.rb +0 -18
  62. data/lib/atmos/commands/otp.rb +0 -54
  63. data/lib/atmos/commands/plan.rb +0 -20
  64. data/lib/atmos/commands/secret.rb +0 -87
  65. data/lib/atmos/commands/terraform.rb +0 -52
  66. data/lib/atmos/commands/user.rb +0 -74
  67. data/lib/atmos/config.rb +0 -208
  68. data/lib/atmos/exceptions.rb +0 -9
  69. data/lib/atmos/generator.rb +0 -199
  70. data/lib/atmos/generator_factory.rb +0 -93
  71. data/lib/atmos/ipc.rb +0 -132
  72. data/lib/atmos/ipc_actions/notify.rb +0 -27
  73. data/lib/atmos/ipc_actions/ping.rb +0 -19
  74. data/lib/atmos/logging.rb +0 -160
  75. data/lib/atmos/otp.rb +0 -61
  76. data/lib/atmos/provider_factory.rb +0 -19
  77. data/lib/atmos/providers/aws/account_manager.rb +0 -82
  78. data/lib/atmos/providers/aws/auth_manager.rb +0 -208
  79. data/lib/atmos/providers/aws/container_manager.rb +0 -116
  80. data/lib/atmos/providers/aws/provider.rb +0 -51
  81. data/lib/atmos/providers/aws/s3_secret_manager.rb +0 -49
  82. data/lib/atmos/providers/aws/user_manager.rb +0 -211
  83. data/lib/atmos/settings_hash.rb +0 -90
  84. data/lib/atmos/terraform_executor.rb +0 -267
  85. data/lib/atmos/ui.rb +0 -159
  86. data/lib/atmos/utils.rb +0 -50
  87. data/lib/atmos/version.rb +0 -3
@@ -1,20 +0,0 @@
1
- require_relative 'terraform'
2
-
3
- module Atmos::Commands
4
-
5
- class Plan < Atmos::Commands::Terraform
6
-
7
- def self.description
8
- "Runs terraform plan"
9
- end
10
-
11
- def execute
12
- args = ["plan"]
13
- args << "--get-modules" unless Atmos.config["disable_auto_modules"].to_s == "true"
14
- @terraform_arguments.insert(0, *args)
15
- super
16
- end
17
-
18
- end
19
-
20
- end
@@ -1,87 +0,0 @@
1
- require_relative 'base_command'
2
- require 'climate_control'
3
-
4
- module Atmos::Commands
5
-
6
- class Secret < BaseCommand
7
-
8
- def self.description
9
- "Manages application secrets"
10
- end
11
-
12
- subcommand "get", "Gets the secret value" do
13
-
14
- parameter "KEY",
15
- "The secret key"
16
-
17
- def execute
18
-
19
- Atmos.config.provider.auth_manager.authenticate(ENV) do |auth_env|
20
- ClimateControl.modify(auth_env) do
21
- value = Atmos.config.provider.secret_manager.get(key)
22
- logger.info "Secret value for #{key}: #{value}"
23
- end
24
- end
25
-
26
- end
27
-
28
- end
29
-
30
- subcommand "set", "Sets the secret value" do
31
-
32
- parameter "KEY",
33
- "The secret key"
34
-
35
- parameter "VALUE",
36
- "The secret value"
37
-
38
- def execute
39
-
40
- Atmos.config.provider.auth_manager.authenticate(ENV) do |auth_env|
41
- ClimateControl.modify(auth_env) do
42
- Atmos.config.provider.secret_manager.set(key, value)
43
- logger.info "Secret set for #{key}"
44
- end
45
- end
46
-
47
- end
48
-
49
- end
50
-
51
- subcommand "list", "Lists all secret keys" do
52
-
53
- def execute
54
-
55
- Atmos.config.provider.auth_manager.authenticate(ENV) do |auth_env|
56
- ClimateControl.modify(auth_env) do
57
- logger.info "Secret keys are:"
58
- Atmos.config.provider.secret_manager.to_h.keys.each {|k| logger.info k}
59
- end
60
- end
61
-
62
- end
63
-
64
- end
65
-
66
- subcommand "delete", "Deletes the secret key/value" do
67
-
68
- parameter "KEY",
69
- "The secret key"
70
-
71
- def execute
72
-
73
- Atmos.config.provider.auth_manager.authenticate(ENV) do |auth_env|
74
- ClimateControl.modify(auth_env) do
75
- value = Atmos.config.provider.secret_manager.get(key)
76
- Atmos.config.provider.secret_manager.delete(key)
77
- logger.info "Deleted secret: #{key}=#{value}"
78
- end
79
- end
80
-
81
- end
82
-
83
- end
84
-
85
- end
86
-
87
- end
@@ -1,52 +0,0 @@
1
- require_relative 'base_command'
2
- require_relative '../../atmos/terraform_executor'
3
-
4
- module Atmos::Commands
5
-
6
- class Terraform < BaseCommand
7
-
8
- def self.description
9
- "Runs terraform"
10
- end
11
-
12
- # override so we can pass all options/flags/parameters directly to
13
- # terraform instead of having clamp parse them
14
- def parse(arguments)
15
- @terraform_arguments = arguments
16
- end
17
-
18
- def execute
19
-
20
- unless Atmos.config.is_atmos_repo?
21
- signal_usage_error <<~EOF
22
- Atmos can only run terraform from a location configured for atmos.
23
- Have you run atmos init?"
24
- EOF
25
- end
26
-
27
- Atmos.config.provider.auth_manager.authenticate(ENV) do |auth_env|
28
- begin
29
-
30
- # TODO: hack to allow apply/etc for bootstrap group
31
- # Fix this once we allow more extensive recipe grouping
32
- working_group = 'default'
33
- @terraform_arguments.each_with_index do |a, i|
34
- if a == "--group"
35
- @terraform_arguments.delete_at(i)
36
- working_group = @terraform_arguments.delete_at(i)
37
- break
38
- end
39
- end
40
-
41
- exe = Atmos::TerraformExecutor.new(process_env: auth_env, working_group: working_group)
42
- get_modules = @terraform_arguments.delete("--get-modules")
43
- exe.run(*@terraform_arguments, get_modules: get_modules.present?)
44
- rescue Atmos::TerraformExecutor::ProcessFailed => e
45
- logger.error(e.message)
46
- end
47
- end
48
- end
49
-
50
- end
51
-
52
- end
@@ -1,74 +0,0 @@
1
- require_relative 'base_command'
2
- require 'climate_control'
3
-
4
- module Atmos::Commands
5
-
6
- class User < BaseCommand
7
-
8
- def self.description
9
- "Manages users in the cloud provider"
10
- end
11
-
12
- subcommand "create", "Create a new user" do
13
-
14
- option ["-f", "--force"],
15
- :flag, "forces deletion/updates for pre-existing resources\n",
16
- default: false
17
-
18
- option ["-l", "--login"],
19
- :flag, "generate a login password\n",
20
- default: false
21
-
22
- option ["-m", "--mfa"],
23
- :flag, "setup a mfa device\n",
24
- default: false
25
-
26
- option ["-k", "--key"],
27
- :flag, "create access keys\n",
28
- default: false
29
-
30
- option ["-p", "--public-key"],
31
- "PUBLIC_KEY", "add ssh public key\n"
32
-
33
- option ["-g", "--group"],
34
- "GROUP",
35
- "associate the given groups to new user\n",
36
- multivalued: true
37
-
38
- parameter "USERNAME",
39
- "The username of the user to add\nShould be an email address" do |u|
40
- raise ArgumentError.new("Not an email") if u !~ URI::MailTo::EMAIL_REGEXP
41
- u
42
- end
43
-
44
- def execute
45
-
46
- Atmos.config.provider.auth_manager.authenticate(ENV) do |auth_env|
47
- ClimateControl.modify(auth_env) do
48
- manager = Atmos.config.provider.user_manager
49
- user = manager.create_user(username)
50
- user.merge!(manager.set_groups(username, group_list, force: force?)) if group_list.present?
51
- user.merge!(manager.enable_login(username, force: force?)) if login?
52
- user.merge!(manager.enable_mfa(username, force: force?)) if mfa?
53
- user.merge!(manager.enable_access_keys(username, force: force?)) if key?
54
- user.merge!(manager.set_public_key(username, public_key, force: force?)) if public_key.present?
55
-
56
- logger.info "\nUser created:\n#{display user}\n"
57
-
58
- if mfa? && user[:mfa_secret]
59
- save_mfa = agree("Save the MFA secret for runtime integration with auth? ") {|q|
60
- q.default = 'y'
61
- }
62
- Atmos::Otp.instance.save if save_mfa
63
- end
64
-
65
- end
66
- end
67
-
68
- end
69
-
70
- end
71
-
72
- end
73
-
74
- end
data/lib/atmos/config.rb DELETED
@@ -1,208 +0,0 @@
1
- require_relative '../atmos'
2
- require_relative '../atmos/settings_hash'
3
- require_relative '../atmos/provider_factory'
4
- require 'yaml'
5
- require 'fileutils'
6
- require 'find'
7
-
8
- module Atmos
9
- class Config
10
- include GemLogger::LoggerSupport
11
- include FileUtils
12
-
13
- attr_accessor :atmos_env, :root_dir,
14
- :config_file, :configs_dir,
15
- :tmp_root
16
-
17
- def initialize(atmos_env)
18
- @atmos_env = atmos_env
19
- @root_dir = File.expand_path(Dir.pwd)
20
- @config_file = File.join(root_dir, "config", "atmos.yml")
21
- @configs_dir = File.join(root_dir, "config", "atmos")
22
- @tmp_root = File.join(root_dir, "tmp")
23
- end
24
-
25
- def is_atmos_repo?
26
- File.exist?(config_file)
27
- end
28
-
29
- def [](key)
30
- load
31
- result = @config.notation_get(key)
32
- return result
33
- end
34
-
35
- def to_h
36
- load
37
- @config.to_hash
38
- end
39
-
40
- def provider
41
- @provider ||= Atmos::ProviderFactory.get(self[:provider])
42
- end
43
-
44
- def all_env_names
45
- load
46
- @full_config[:environments].keys
47
- end
48
-
49
- def account_hash
50
- load
51
- environments = @full_config[:environments] || {}
52
- environments.inject(Hash.new) do |accum, entry|
53
- accum[entry.first] = entry.last[:account_id]
54
- accum
55
- end
56
- end
57
-
58
- def tmp_dir
59
- @tmp_dir ||= begin
60
- dir = File.join(tmp_root, atmos_env)
61
- logger.debug("Tmp dir: #{dir}")
62
- mkdir_p(dir)
63
- dir
64
- end
65
- end
66
-
67
- def auth_cache_dir
68
- @auth_cache_dir ||= begin
69
- dir = File.join(tmp_dir, 'auth')
70
- logger.debug("Auth cache dir: #{dir}")
71
- mkdir_p(dir)
72
- dir
73
- end
74
- end
75
-
76
- def tf_working_dir(group='default')
77
- @tf_working_dir ||= {}
78
- @tf_working_dir[group] ||= begin
79
- dir = File.join(tmp_dir, 'tf', group)
80
- logger.debug("Terraform working dir: #{dir}")
81
- mkdir_p(dir)
82
- dir
83
- end
84
- end
85
-
86
- private
87
-
88
- INTERP_PATTERN = /(\#\{([^\}]+)\})/
89
-
90
- def load
91
- @config ||= begin
92
-
93
- logger.debug("Atmos env: #{atmos_env}")
94
-
95
- if ! File.exist?(config_file)
96
- logger.warn "Could not find an atmos config file at: #{config_file}"
97
- # raise RuntimeError.new("Could not find an atmos config file at: #{config_file}")
98
- end
99
-
100
- logger.debug("Loading atmos config file #{config_file}")
101
- @full_config = SettingsHash.new((YAML.load_file(config_file) rescue Hash.new))
102
-
103
- if Dir.exist?(configs_dir)
104
- logger.debug("Loading atmos config files from #{configs_dir}")
105
- Find.find(configs_dir) do |f|
106
- if f =~ /\.ya?ml/i
107
- logger.debug("Loading atmos config file: #{f}")
108
- h = SettingsHash.new(YAML.load_file(f))
109
- @full_config = @full_config.merge(h)
110
- end
111
- end
112
- else
113
- logger.debug("Atmos config dir doesn't exist: #{configs_dir}")
114
- end
115
-
116
- @full_config['provider'] = provider_name = @full_config['provider'] || 'aws'
117
- global = SettingsHash.new(@full_config.reject {|k, v| ['environments', 'providers'].include?(k) })
118
- begin
119
- prov = @full_config.deep_fetch(:providers, provider_name)
120
- rescue
121
- logger.debug("No provider config found for '#{provider_name}'")
122
- prov = {}
123
- end
124
-
125
- begin
126
- env = @full_config.deep_fetch(:environments, atmos_env)
127
- rescue
128
- logger.debug("No environment config found for '#{atmos_env}'")
129
- env = {}
130
- end
131
-
132
- conf = global.deep_merge(prov).
133
- deep_merge(env).
134
- deep_merge(
135
- atmos_env: atmos_env,
136
- atmos_version: Atmos::VERSION
137
- )
138
- expand(conf, conf)
139
- end
140
- end
141
-
142
- def expand(config, obj)
143
- case obj
144
- when Hash
145
- SettingsHash.new(Hash[obj.collect {|k, v| [k, expand(config, v)] }])
146
- when Array
147
- obj.collect {|i| expand(config, i) }
148
- when String
149
- result = obj
150
- result.scan(INTERP_PATTERN).each do |substr, statement|
151
- # TODO: check for cycles
152
- if statement =~ /^[\w\.\[\]]$/
153
- val = config.notation_get(statement)
154
- else
155
- # TODO: be consistent with dot notation between eval and
156
- # notation_get. eval ends up calling Hashie method_missing,
157
- # which returns nil if a key doesn't exist, causing a nil
158
- # exception for next item in chain, while notation_get returns
159
- # nil gracefully for the entire chain (preferred)
160
- begin
161
- val = eval(statement, config.instance_eval("binding"))
162
- rescue => e
163
- file, line = find_config_error(substr)
164
- file_msg = file.nil? ? "" : " in #{File.basename(file)}:#{line}"
165
- raise RuntimeError.new("Failing config statement '#{substr}'#{file_msg} => #{e.class} #{e.message}")
166
- end
167
- end
168
- result = result.sub(substr, expand(config, val).to_s)
169
- end
170
- result = true if result == 'true'
171
- result = false if result == 'false'
172
- result
173
- else
174
- obj
175
- end
176
- end
177
-
178
- def find_config_error(statement)
179
- filename = nil
180
- line = 0
181
-
182
- configs = []
183
- configs << config_file if File.exist?(config_file)
184
- if Dir.exist?(configs_dir)
185
- Find.find(configs_dir) do |f|
186
- if f =~ /\.ya?ml/i
187
- configs << f
188
- end
189
- end
190
- end
191
-
192
- configs.each do |c|
193
- current_line = 0
194
- File.foreach(c) do |f|
195
- current_line += 1
196
- if f.include?(statement)
197
- filename = c
198
- line = current_line
199
- break
200
- end
201
- end
202
- end
203
-
204
- return filename, line
205
- end
206
- end
207
-
208
- end
@@ -1,9 +0,0 @@
1
- require_relative '../atmos'
2
-
3
- module Atmos
4
- module Exceptions
5
- class UsageError < Clamp::UsageError
6
-
7
- end
8
- end
9
- end