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,65 +0,0 @@
1
- require_relative 'base_command'
2
- require_relative '../../atmos/settings_hash'
3
- require 'climate_control'
4
-
5
- module Atmos::Commands
6
-
7
- class Account < BaseCommand
8
-
9
- def self.description
10
- "Manages accounts/envs in the cloud provider"
11
- end
12
-
13
- subcommand "create", "Create a new account" do
14
-
15
- option ["-s", "--source-env"],
16
- "SOURCE_ENV", "Base the new env on a clone of the given one\n"
17
-
18
- option ["-e", "--email"],
19
- "EMAIL", "override default email used for new account\n"
20
-
21
- option ["-n", "--name"],
22
- "NAME", "override default name used for new account\n"
23
-
24
- parameter "ENV",
25
- "The name of the new env to create"
26
-
27
- def execute
28
-
29
- Atmos.config.provider.auth_manager.authenticate(ENV) do |auth_env|
30
- ClimateControl.modify(auth_env) do
31
-
32
- config = YAML.load_file(Atmos.config.config_file)
33
-
34
- if config['environments'][env]
35
- signal_usage_error "Env '#{env}' is already present in atmos config"
36
- end
37
-
38
- source = {}
39
- if source_env.present?
40
- source = config['environments'][source_env]
41
- if source.blank?
42
- signal_usage_error "Source env '#{source_env}' does not exist"
43
- end
44
- source = source.clone
45
- end
46
-
47
- account = Atmos.config.provider.account_manager.create_account(env, name: name, email: email)
48
- logger.info "Account created: #{display account}"
49
-
50
- source['account_id'] = account[:account_id].to_s
51
-
52
- new_yml = Atmos::SettingsHash.add_config(
53
- Atmos.config.config_file,
54
- "environments.#{env}", source
55
- )
56
- logger.info("Writing out new atmos.yml containing new account")
57
- File.write(Atmos.config.config_file, new_yml)
58
- end
59
- end
60
- end
61
- end
62
-
63
- end
64
-
65
- end
@@ -1,20 +0,0 @@
1
- require_relative 'terraform'
2
-
3
- module Atmos::Commands
4
-
5
- class Apply < Atmos::Commands::Terraform
6
-
7
- def self.description
8
- "Runs terraform apply"
9
- end
10
-
11
- def execute
12
- args = ["apply"]
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,29 +0,0 @@
1
- require_relative 'base_command'
2
- require 'climate_control'
3
-
4
- module Atmos::Commands
5
-
6
- class AuthExec < BaseCommand
7
-
8
- def self.description
9
- "Exec subprocess with an authenticated environment"
10
- end
11
-
12
- option ["-r", "--role"],
13
- 'ROLE', "overrides assume role name\n"
14
-
15
- parameter "COMMAND ...", "command to exec", :attribute_name => :command
16
-
17
- def execute
18
- Atmos.config.provider.auth_manager.authenticate(ENV, role: role) do |auth_env|
19
- result = system(auth_env, *command)
20
- if ! result
21
- logger.error("Process failed: #{command}")
22
- exit(1)
23
- end
24
- end
25
-
26
- end
27
-
28
- end
29
- end
@@ -1,12 +0,0 @@
1
- require_relative '../../atmos'
2
- require_relative '../../atmos/ui'
3
- require 'clamp'
4
-
5
- module Atmos::Commands
6
-
7
- class BaseCommand < Clamp::Command
8
- include GemLogger::LoggerSupport
9
- include Atmos::UI
10
- end
11
-
12
- end
@@ -1,72 +0,0 @@
1
- require_relative 'base_command'
2
-
3
- module Atmos::Commands
4
-
5
- class Bootstrap < BaseCommand
6
-
7
- def self.description
8
- "Sets up the initial aws account for use by atmos"
9
- end
10
-
11
- option ["-f", "--force"],
12
- :flag, "forces bootstrap\n"
13
-
14
- def execute
15
-
16
- tf_init_dir = File.join(Atmos.config.tf_working_dir('bootstrap'), '.terraform')
17
- tf_initialized = File.exist?(tf_init_dir)
18
- backend_initialized = File.exist?(File.join(tf_init_dir, 'terraform.tfstate'))
19
-
20
- rebootstrap_msg = <<~EOF
21
- Bootstrap should only be performed when provisioning an account for the first
22
- time. Try 'atmos terraform init'
23
- EOF
24
-
25
- if !force? && tf_initialized
26
- signal_usage_error(rebootstrap_msg)
27
- end
28
-
29
- Atmos.config.provider.auth_manager.authenticate(ENV, bootstrap: true) do |auth_env|
30
- begin
31
- exe = Atmos::TerraformExecutor.new(process_env: auth_env, working_group: 'bootstrap')
32
-
33
- skip_backend = true
34
- skip_secrets = true
35
- if backend_initialized
36
- skip_backend = false
37
- skip_secrets = false
38
- end
39
-
40
- # Cases
41
- # 1) bootstrap of new account - success
42
- # 2) repeating bootstrap of new account due to failure partway - success
43
- # 3) try to rebootstrap existing account on fresh checkout - should fail trying to create resources of same name, check output for this?
44
- # 4) bootstrap new account with no-default secrets
45
-
46
- # Need to init before we can create the resources to store state in bootstrap
47
- exe.run("init", "-input=false", "-lock=false",
48
- skip_backend: true, skip_secrets: true)
49
-
50
- # Bootstrap to create the resources needed to store state
51
- exe.run("apply", "-input=false",
52
- skip_backend: true, skip_secrets: true)
53
-
54
- # Need to init to setup the backend state after we create the resources
55
- # to store state in bootstrap
56
- exe.run("init", "-input=false", "-force-copy", skip_secrets: true)
57
-
58
- # Might as well init the non-bootstrap case as well once the state
59
- # storage has been setup in bootstrap
60
- exe = Atmos::TerraformExecutor.new(process_env: auth_env)
61
- exe.run("init", "-input=false", skip_secrets: true)
62
-
63
- rescue Atmos::TerraformExecutor::ProcessFailed => e
64
- logger.error(e.message)
65
- logger.error(rebootstrap_msg)
66
- end
67
- end
68
- end
69
-
70
- end
71
-
72
- end
@@ -1,58 +0,0 @@
1
- require_relative 'base_command'
2
- require_relative '../../atmos/settings_hash'
3
- require 'climate_control'
4
-
5
- module Atmos::Commands
6
-
7
- class Container < BaseCommand
8
-
9
- def self.description
10
- "Manages containers in the cloud provider"
11
- end
12
-
13
- subcommand "deploy", "Deploy a container" do
14
-
15
- option ["-c", "--cluster"],
16
- "CLUSTER", "The cluster name\n",
17
- required: true
18
-
19
- option ["-r", "--role"],
20
- "ROLE", "The role to assume when deploying\n"
21
-
22
- option ["-i", "--image"],
23
- "IMAGE", "The local container image to deploy\nDefaults to service/task name"
24
-
25
- option ["-t", "--task"],
26
- :flag, "Deploy as a task, not a service\n"
27
-
28
- option ["-v", "--revision"],
29
- "REVISION", "Use as the remote image revision\n"
30
-
31
- parameter "NAME",
32
- "The name of the service (or task) to deploy"
33
-
34
- def default_image
35
- name
36
- end
37
-
38
- def execute
39
- Atmos.config.provider.auth_manager.authenticate(ENV, role: role) do |auth_env|
40
- ClimateControl.modify(auth_env) do
41
- mgr = Atmos.config.provider.container_manager
42
-
43
- result = mgr.push(name, image, revision: revision)
44
- if task?
45
- result = result.merge(mgr.deploy_task(name, result[:remote_image]))
46
- else
47
- result = result.merge(mgr.deploy_service(cluster, name, result[:remote_image]))
48
- end
49
-
50
- logger.info "Container deployed:\n #{display result}"
51
- end
52
- end
53
- end
54
- end
55
-
56
- end
57
-
58
- end
@@ -1,18 +0,0 @@
1
- require_relative 'terraform'
2
-
3
- module Atmos::Commands
4
-
5
- class Destroy < Atmos::Commands::Terraform
6
-
7
- def self.description
8
- "Runs terraform destroy"
9
- end
10
-
11
- def execute
12
- @terraform_arguments.insert(0, "destroy")
13
- super
14
- end
15
-
16
- end
17
-
18
- end
@@ -1,90 +0,0 @@
1
- require_relative 'base_command'
2
- require_relative '../../atmos/generator_factory'
3
- require_relative '../../atmos/utils'
4
-
5
- module Atmos::Commands
6
-
7
- # From https://github.com/rubber/rubber/blob/master/lib/rubber/commands/vulcanize.rb
8
- class Generate < BaseCommand
9
-
10
- def self.description
11
- <<~EOF
12
- Installs configuration templates used by atmos to create infrastructure
13
- resources e.g.
14
-
15
- atmos generate aws-vpc
16
-
17
- use --list to get a list of the template names for a given sourceroot
18
- EOF
19
- end
20
-
21
- option ["-f", "--force"],
22
- :flag, "Overwrite files that already exist"
23
- option ["-n", "--dryrun"],
24
- :flag, "Run but do not make any changes"
25
- option ["-q", "--quiet"],
26
- :flag, "Supress status output"
27
- option ["-s", "--skip"],
28
- :flag, "Skip files that already exist"
29
- option ["-d", "--[no-]dependencies"],
30
- :flag, "Walk dependencies, or not", default: true
31
- option ["-l", "--list"],
32
- :flag, "list available templates\n"
33
- option ["-p", "--sourcepath"],
34
- "PATH", "find templates at given path or github url\n",
35
- multivalued: true
36
-
37
- parameter "TEMPLATE ...", "atmos template(s)", required: false
38
-
39
- def execute
40
- signal_usage_error "template name is required" if template_list.blank? && ! list?
41
-
42
- # don't want to fail for new repo
43
- if Atmos.config && Atmos.config.is_atmos_repo?
44
- config_sourcepaths = Atmos.config['template_sources'].try(:collect, &:location) || []
45
- sourcepath_list.concat(config_sourcepaths)
46
- end
47
-
48
- # Always search for templates against the bundled templates directory
49
- sourcepath_list << File.expand_path('../../../../templates', __FILE__)
50
-
51
- g = Atmos::GeneratorFactory.create(sourcepath_list,
52
- force: force?,
53
- pretend: dryrun?,
54
- quiet: quiet?,
55
- skip: skip?,
56
- dependencies: dependencies?)
57
- if list?
58
- logger.info "Valid templates are:"
59
- list_templates(g, template_list).each {|l| logger.info(l) }
60
- else
61
- g.generate(template_list)
62
- end
63
-
64
- end
65
-
66
- def list_templates(generator, name_filters)
67
- # Format templates into comma-separated paragraph with limt of 70 characters per line
68
- filtered_names = generator.valid_templates.select do |name|
69
- name_filters.blank? || name_filters.any? {|f| name =~ /#{f}/ }
70
- end
71
-
72
- lines = ['']
73
- filtered_names.each do |template_name|
74
- line = lines.last
75
- if line.size == 0
76
- line << template_name
77
- elsif line.size + template_name.size > 68
78
- line << ','
79
- lines << template_name # new line
80
- else
81
- line << ", " + template_name
82
- end
83
- end
84
-
85
- return lines
86
- end
87
-
88
- end
89
-
90
- end
@@ -1,18 +0,0 @@
1
- require_relative 'terraform'
2
-
3
- module Atmos::Commands
4
-
5
- class Init < Atmos::Commands::Terraform
6
-
7
- def self.description
8
- "Runs terraform init"
9
- end
10
-
11
- def execute
12
- @terraform_arguments.insert(0, "init")
13
- super
14
- end
15
-
16
- end
17
-
18
- end
@@ -1,18 +0,0 @@
1
- require_relative 'generate'
2
-
3
- module Atmos::Commands
4
-
5
- class New < Atmos::Commands::Generate
6
-
7
- def self.description
8
- "Sets up a new atmos project in the current directory"
9
- end
10
-
11
- def execute
12
- template_list << "new"
13
- super
14
- end
15
-
16
- end
17
-
18
- end
@@ -1,54 +0,0 @@
1
- require_relative 'base_command'
2
- require_relative '../../atmos/otp'
3
- require 'clipboard'
4
-
5
- module Atmos::Commands
6
-
7
- class Otp < BaseCommand
8
-
9
- def self.description
10
- "Generates an otp token for the given user"
11
- end
12
-
13
- option ["-s", "--secret"],
14
- 'SECRET', "The otp secret\nWill save for future use"
15
-
16
- option ["-c", "--clipboard"],
17
- :flag,
18
- <<~EOF
19
- Automatically copy the token to the system
20
- clipboard. For dependencies see:
21
- https://github.com/janlelis/clipboard
22
- EOF
23
-
24
- parameter "NAME",
25
- "The otp name (IAM username)"
26
-
27
- def execute
28
- code = nil
29
- if secret
30
- Atmos::Otp.instance.add(name, secret)
31
- code = Atmos::Otp.instance.generate(name)
32
- Atmos::Otp.instance.save
33
- else
34
- code = Atmos::Otp.instance.generate(name)
35
- end
36
-
37
- if code.nil?
38
- signal_usage_error <<~EOF
39
- No otp secret has been setup for #{name}
40
- Use the -m flag to 'atmos user create' to create/activate one
41
- or associate an existing secret with 'atmos otp -s <secret> <name>'
42
- EOF
43
- else
44
- puts code
45
- end
46
-
47
- if clipboard?
48
- Clipboard.copy(code)
49
- end
50
- end
51
-
52
- end
53
-
54
- end