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.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/exe/atmos +2 -2
- data/lib/{atmos.rb → simplygenius/atmos.rb} +9 -7
- data/lib/simplygenius/atmos/cli.rb +116 -0
- data/lib/simplygenius/atmos/commands/account.rb +69 -0
- data/lib/simplygenius/atmos/commands/apply.rb +24 -0
- data/lib/simplygenius/atmos/commands/auth_exec.rb +34 -0
- data/lib/simplygenius/atmos/commands/base_command.rb +16 -0
- data/lib/simplygenius/atmos/commands/bootstrap.rb +76 -0
- data/lib/simplygenius/atmos/commands/container.rb +62 -0
- data/lib/simplygenius/atmos/commands/destroy.rb +22 -0
- data/lib/simplygenius/atmos/commands/generate.rb +187 -0
- data/lib/simplygenius/atmos/commands/init.rb +22 -0
- data/lib/simplygenius/atmos/commands/new.rb +22 -0
- data/lib/simplygenius/atmos/commands/otp.rb +58 -0
- data/lib/simplygenius/atmos/commands/plan.rb +24 -0
- data/lib/simplygenius/atmos/commands/secret.rb +91 -0
- data/lib/simplygenius/atmos/commands/terraform.rb +56 -0
- data/lib/simplygenius/atmos/commands/user.rb +78 -0
- data/lib/simplygenius/atmos/config.rb +279 -0
- data/lib/simplygenius/atmos/exceptions.rb +13 -0
- data/lib/simplygenius/atmos/generator.rb +232 -0
- data/lib/simplygenius/atmos/ipc.rb +136 -0
- data/lib/simplygenius/atmos/ipc_actions/notify.rb +31 -0
- data/lib/simplygenius/atmos/ipc_actions/ping.rb +23 -0
- data/lib/simplygenius/atmos/logging.rb +164 -0
- data/lib/simplygenius/atmos/otp.rb +62 -0
- data/lib/simplygenius/atmos/plugin.rb +27 -0
- data/lib/simplygenius/atmos/plugin_manager.rb +120 -0
- data/lib/simplygenius/atmos/plugins/output_filter.rb +29 -0
- data/lib/simplygenius/atmos/plugins/prompt_notify.rb +21 -0
- data/lib/simplygenius/atmos/provider_factory.rb +23 -0
- data/lib/simplygenius/atmos/providers/aws/account_manager.rb +83 -0
- data/lib/simplygenius/atmos/providers/aws/auth_manager.rb +220 -0
- data/lib/simplygenius/atmos/providers/aws/container_manager.rb +118 -0
- data/lib/simplygenius/atmos/providers/aws/provider.rb +53 -0
- data/lib/simplygenius/atmos/providers/aws/s3_secret_manager.rb +51 -0
- data/lib/simplygenius/atmos/providers/aws/user_manager.rb +213 -0
- data/lib/simplygenius/atmos/settings_hash.rb +93 -0
- data/lib/simplygenius/atmos/source_path.rb +186 -0
- data/lib/simplygenius/atmos/template.rb +117 -0
- data/lib/simplygenius/atmos/terraform_executor.rb +297 -0
- data/lib/simplygenius/atmos/ui.rb +173 -0
- data/lib/simplygenius/atmos/utils.rb +54 -0
- data/lib/simplygenius/atmos/version.rb +5 -0
- data/templates/new/config/atmos.yml +21 -13
- data/templates/new/config/atmos/recipes.yml +16 -0
- data/templates/new/config/atmos/runtime.yml +9 -0
- metadata +46 -40
- data/lib/atmos/cli.rb +0 -105
- data/lib/atmos/commands/account.rb +0 -65
- data/lib/atmos/commands/apply.rb +0 -20
- data/lib/atmos/commands/auth_exec.rb +0 -29
- data/lib/atmos/commands/base_command.rb +0 -12
- data/lib/atmos/commands/bootstrap.rb +0 -72
- data/lib/atmos/commands/container.rb +0 -58
- data/lib/atmos/commands/destroy.rb +0 -18
- data/lib/atmos/commands/generate.rb +0 -90
- data/lib/atmos/commands/init.rb +0 -18
- data/lib/atmos/commands/new.rb +0 -18
- data/lib/atmos/commands/otp.rb +0 -54
- data/lib/atmos/commands/plan.rb +0 -20
- data/lib/atmos/commands/secret.rb +0 -87
- data/lib/atmos/commands/terraform.rb +0 -52
- data/lib/atmos/commands/user.rb +0 -74
- data/lib/atmos/config.rb +0 -208
- data/lib/atmos/exceptions.rb +0 -9
- data/lib/atmos/generator.rb +0 -199
- data/lib/atmos/generator_factory.rb +0 -93
- data/lib/atmos/ipc.rb +0 -132
- data/lib/atmos/ipc_actions/notify.rb +0 -27
- data/lib/atmos/ipc_actions/ping.rb +0 -19
- data/lib/atmos/logging.rb +0 -160
- data/lib/atmos/otp.rb +0 -61
- data/lib/atmos/provider_factory.rb +0 -19
- data/lib/atmos/providers/aws/account_manager.rb +0 -82
- data/lib/atmos/providers/aws/auth_manager.rb +0 -208
- data/lib/atmos/providers/aws/container_manager.rb +0 -116
- data/lib/atmos/providers/aws/provider.rb +0 -51
- data/lib/atmos/providers/aws/s3_secret_manager.rb +0 -49
- data/lib/atmos/providers/aws/user_manager.rb +0 -211
- data/lib/atmos/settings_hash.rb +0 -90
- data/lib/atmos/terraform_executor.rb +0 -267
- data/lib/atmos/ui.rb +0 -159
- data/lib/atmos/utils.rb +0 -50
- 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
|
data/lib/atmos/commands/apply.rb
DELETED
@@ -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,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
|
data/lib/atmos/commands/init.rb
DELETED
@@ -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
|
data/lib/atmos/commands/new.rb
DELETED
@@ -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
|
data/lib/atmos/commands/otp.rb
DELETED
@@ -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
|