simplygenius-atmos 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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