envirobly 1.6.0 → 1.6.1
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.
- checksums.yaml +4 -4
- data/lib/envirobly/cli/main.rb +3 -3
- data/lib/envirobly/container_shell.rb +115 -91
- data/lib/envirobly/deployment.rb +85 -72
- data/lib/envirobly/target.rb +87 -0
- data/lib/envirobly/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49c3237a5570bb1839a02b5cbdfb3c70725c6e200841a09b7299b46e62efb3c2
|
4
|
+
data.tar.gz: b90bcd5afcf383bfdac23320870c3c420cf30b842f1ec67dba152f94a9382ef3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c57b8f6e3e791afc1d392db80f501e1ee10cc7229465b3c3e10e300fe3f786ace269b79660b624ef099b2e0e1eddc8c9d4e03e8ac05d20b73f824f896223b6b9
|
7
|
+
data.tar.gz: 448da4b7847e9d067e722bbfcb1b011e3573259225a0ff2bf0114b8c757195d9b4d78096c47fccd137aade3d5508acafb19fba73a00a55b14454618b882c6ef7
|
data/lib/envirobly/cli/main.rb
CHANGED
@@ -101,7 +101,7 @@ class Envirobly::Cli::Main < Envirobly::Base
|
|
101
101
|
region: options.region,
|
102
102
|
project_id: options.project_id,
|
103
103
|
project_name: options.project_name,
|
104
|
-
environ_name: environ_name.presence
|
104
|
+
environ_name: environ_name.presence,
|
105
105
|
commit:,
|
106
106
|
shell:
|
107
107
|
)
|
@@ -128,7 +128,7 @@ class Envirobly::Cli::Main < Envirobly::Base
|
|
128
128
|
method_option :shell, type: :string
|
129
129
|
method_option :user, type: :string
|
130
130
|
def exec(service_name, *command)
|
131
|
-
Envirobly::ContainerShell.new(service_name, options).exec(command)
|
131
|
+
Envirobly::ContainerShell.new(service_name, options, shell:).exec(command)
|
132
132
|
end
|
133
133
|
|
134
134
|
desc "rsync [SERVICE_NAME:]SOURCE_PATH [SERVICE_NAME:]DESTINATION_PATH", <<~TXT
|
@@ -149,6 +149,6 @@ class Envirobly::Cli::Main < Envirobly::Base
|
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
-
Envirobly::ContainerShell.new(service_name, options).rsync(source, destination)
|
152
|
+
Envirobly::ContainerShell.new(service_name, options, shell:).rsync(source, destination)
|
153
153
|
end
|
154
154
|
end
|
@@ -1,113 +1,137 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
3
|
+
module Envirobly
|
4
|
+
class ContainerShell
|
5
|
+
AWS_ENV = [
|
6
|
+
"AWS_ACCESS_KEY_ID='%s'",
|
7
|
+
"AWS_SECRET_ACCESS_KEY='%s'",
|
8
|
+
"AWS_SESSION_TOKEN='%s'"
|
9
|
+
]
|
10
|
+
SSH = [
|
11
|
+
"ssh -i %s",
|
12
|
+
"-o StrictHostKeyChecking=no",
|
13
|
+
"-o UserKnownHostsFile=/dev/null",
|
14
|
+
"-o SendEnv=ENVIROBLY_SERVICE_INTERACTIVE_SHELL",
|
15
|
+
"-o SendEnv=ENVIROBLY_SERVICE_SHELL_USER",
|
16
|
+
"-o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id %s --region %s'"
|
17
|
+
]
|
18
|
+
USER_AND_HOST = "envirobly-service@%s"
|
19
|
+
|
20
|
+
attr_reader :options, :service_name
|
21
|
+
|
22
|
+
def initialize(service_name, options, shell:)
|
23
|
+
@service_name = service_name
|
24
|
+
@options = options
|
25
|
+
|
26
|
+
commit = Git::Commit.new "HEAD"
|
27
|
+
default_account = Defaults::Account.new(shell:)
|
28
|
+
default_project = Defaults::Project.new(shell:)
|
29
|
+
|
30
|
+
target = Target.new(
|
31
|
+
default_account_id: default_account.value,
|
32
|
+
default_project_id: default_project.value,
|
33
|
+
default_project_name: Defaults::Project.dirname,
|
34
|
+
default_environ_name: commit.current_branch,
|
35
|
+
account_id: options.account_id,
|
36
|
+
project_id: options.project_id,
|
37
|
+
project_name: options.project_name,
|
38
|
+
environ_name: options.environ_name
|
39
|
+
)
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
41
|
+
if target.missing_params.include?(:account_id)
|
42
|
+
target.account_id = default_account.require_value
|
43
|
+
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
env_vars,
|
50
|
-
%(rsync #{options.args} -e "#{ssh}"),
|
51
|
-
source.sub("#{service_name}:", "#{user_and_host}:"),
|
52
|
-
destination.sub("#{service_name}:", "#{user_and_host}:")
|
53
|
-
)
|
54
|
-
end
|
55
|
-
end
|
45
|
+
target.ignored_params.each do |param|
|
46
|
+
shell.say "--#{param.to_s.parameterize} ignored, due to other arguments overriding it"
|
47
|
+
end
|
56
48
|
|
57
|
-
|
58
|
-
|
59
|
-
|
49
|
+
@params = {
|
50
|
+
account_id: target.account_id,
|
51
|
+
project_id: target.project_id,
|
52
|
+
project_name: target.project_name,
|
53
|
+
environ_name: target.environ_name,
|
54
|
+
service_name:,
|
55
|
+
instance_slot: options.instance_slot || 0
|
56
|
+
}
|
57
|
+
|
58
|
+
if options.project_name.blank? && options.account_id.blank? && options.project_id.blank?
|
59
|
+
@params[:project_id] = Defaults::Project.new.value
|
60
|
+
end
|
60
61
|
end
|
61
62
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
api.create_service_shell_connection(@params).object
|
63
|
+
def exec(command = nil)
|
64
|
+
with_private_key do
|
65
|
+
system join(env_vars, ssh, user_and_host, command)
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
def rsync(source, destination)
|
70
|
+
with_private_key do
|
71
|
+
system join(
|
72
|
+
env_vars,
|
73
|
+
%(rsync #{options.args} -e "#{ssh}"),
|
74
|
+
source.sub("#{service_name}:", "#{user_and_host}:"),
|
75
|
+
destination.sub("#{service_name}:", "#{user_and_host}:")
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
73
79
|
|
74
|
-
|
80
|
+
private
|
81
|
+
def join(*parts)
|
82
|
+
parts.flatten.compact.join(" ")
|
83
|
+
end
|
75
84
|
|
76
|
-
|
85
|
+
def connect_data
|
86
|
+
@connect_data ||= begin
|
87
|
+
api = Api.new
|
88
|
+
api.create_service_shell_connection(@params).object
|
89
|
+
end
|
77
90
|
end
|
78
|
-
end
|
79
91
|
|
80
|
-
|
81
|
-
|
92
|
+
def with_private_key
|
93
|
+
Tempfile.create do |file|
|
94
|
+
file.write connect_data.fetch("instance").fetch("private_key")
|
95
|
+
file.flush
|
82
96
|
|
83
|
-
|
84
|
-
join(AWS_ENV),
|
85
|
-
credentials.fetch("access_key_id"),
|
86
|
-
credentials.fetch("secret_access_key"),
|
87
|
-
credentials.fetch("session_token")
|
88
|
-
)
|
97
|
+
@private_key_path = file.path
|
89
98
|
|
90
|
-
|
91
|
-
|
99
|
+
yield
|
100
|
+
end
|
92
101
|
end
|
93
102
|
|
94
|
-
|
95
|
-
|
96
|
-
end
|
103
|
+
def env_vars
|
104
|
+
credentials = connect_data.fetch("open_tunnel_credentials")
|
97
105
|
|
98
|
-
|
99
|
-
|
106
|
+
result = sprintf(
|
107
|
+
join(AWS_ENV),
|
108
|
+
credentials.fetch("access_key_id"),
|
109
|
+
credentials.fetch("secret_access_key"),
|
110
|
+
credentials.fetch("session_token")
|
111
|
+
)
|
100
112
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
@private_key_path,
|
105
|
-
connect_data.fetch("instance").fetch("aws_id"),
|
106
|
-
connect_data.fetch("region")
|
107
|
-
)
|
108
|
-
end
|
113
|
+
if options.shell.present?
|
114
|
+
result = join "ENVIROBLY_SERVICE_INTERACTIVE_SHELL='#{options.shell}'", result
|
115
|
+
end
|
109
116
|
|
110
|
-
|
111
|
-
|
112
|
-
|
117
|
+
if options.user.present?
|
118
|
+
result = join "ENVIROBLY_SERVICE_SHELL_USER='#{options.user}'", result
|
119
|
+
end
|
120
|
+
|
121
|
+
result
|
122
|
+
end
|
123
|
+
|
124
|
+
def ssh
|
125
|
+
sprintf(
|
126
|
+
join(SSH),
|
127
|
+
@private_key_path,
|
128
|
+
connect_data.fetch("instance").fetch("aws_id"),
|
129
|
+
connect_data.fetch("region")
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def user_and_host
|
134
|
+
sprintf USER_AND_HOST, connect_data.fetch("instance").fetch("private_ipv4")
|
135
|
+
end
|
136
|
+
end
|
113
137
|
end
|
data/lib/envirobly/deployment.rb
CHANGED
@@ -2,95 +2,108 @@
|
|
2
2
|
|
3
3
|
require "yaml"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
5
|
+
module Envirobly
|
6
|
+
class Deployment
|
7
|
+
include Colorize
|
8
|
+
|
9
|
+
attr_reader :params
|
10
|
+
|
11
|
+
def initialize(environ_name:, commit:, account_id:, project_name:, project_id:, region:, shell:)
|
12
|
+
@environ_name = environ_name
|
13
|
+
@commit = commit
|
14
|
+
@config = Config.new
|
15
|
+
@default_account = Defaults::Account.new(shell:)
|
16
|
+
@default_project = Defaults::Project.new(shell:)
|
17
|
+
@default_region = Defaults::Region.new(shell:)
|
18
|
+
|
19
|
+
target = Target.new(
|
20
|
+
default_account_id: @default_account.value,
|
21
|
+
default_project_id: @default_project.value,
|
22
|
+
default_region: @default_region.value,
|
23
|
+
default_project_name: Defaults::Project.dirname,
|
24
|
+
default_environ_name: commit.current_branch,
|
25
|
+
account_id:,
|
26
|
+
project_id:,
|
27
|
+
region:,
|
28
|
+
project_name:,
|
29
|
+
environ_name:
|
30
|
+
)
|
31
|
+
|
32
|
+
if target.missing_params.include?(:account_id)
|
33
|
+
target.account_id = @default_account.require_value
|
34
|
+
end
|
19
35
|
|
20
|
-
|
21
|
-
|
36
|
+
if target.missing_params.include?(:region)
|
37
|
+
target.region = @default_region.require_value
|
38
|
+
end
|
22
39
|
|
23
|
-
|
24
|
-
|
40
|
+
target.ignored_params.each do |param|
|
41
|
+
shell.say "--#{param.to_s.parameterize} ignored, due to other arguments overriding it"
|
25
42
|
end
|
26
|
-
end
|
27
43
|
|
28
|
-
|
29
|
-
|
44
|
+
@params = {
|
45
|
+
account_id: target.account_id,
|
46
|
+
project_id: target.project_id,
|
47
|
+
project_name: target.project_name,
|
48
|
+
region: target.region,
|
49
|
+
deployment: {
|
50
|
+
environ_name: target.environ_name,
|
51
|
+
commit_ref: @commit.ref,
|
52
|
+
commit_time: @commit.time,
|
53
|
+
commit_message: @commit.message,
|
54
|
+
object_tree_checksum: @commit.object_tree_checksum,
|
55
|
+
**@config.to_params
|
56
|
+
}
|
57
|
+
}
|
30
58
|
end
|
31
59
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
deployment: {
|
38
|
-
environ_name:,
|
39
|
-
commit_ref: @commit.ref,
|
40
|
-
commit_time: @commit.time,
|
41
|
-
commit_message: @commit.message,
|
42
|
-
object_tree_checksum: @commit.object_tree_checksum,
|
43
|
-
**@config.to_params
|
44
|
-
}
|
45
|
-
}
|
46
|
-
end
|
60
|
+
def perform(dry_run:)
|
61
|
+
puts [ "Deploying commit", yellow(@commit.short_ref), faint("→"), green(@environ_name) ].join(" ")
|
62
|
+
puts
|
63
|
+
puts " #{@commit.message}"
|
64
|
+
puts
|
47
65
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
puts
|
66
|
+
if dry_run
|
67
|
+
puts YAML.dump(@params)
|
68
|
+
return
|
69
|
+
end
|
53
70
|
|
54
|
-
|
55
|
-
|
56
|
-
return
|
57
|
-
end
|
71
|
+
# Create deployment
|
72
|
+
api = Api.new
|
58
73
|
|
59
|
-
|
60
|
-
|
74
|
+
Duration.measure do
|
75
|
+
response = api.create_deployment @params
|
61
76
|
|
62
|
-
|
63
|
-
|
77
|
+
unless response.success?
|
78
|
+
display_config_errors response.object.fetch("errors")
|
79
|
+
exit 1
|
80
|
+
end
|
64
81
|
|
65
|
-
|
66
|
-
display_config_errors response.object.fetch("errors")
|
67
|
-
exit 1
|
68
|
-
end
|
82
|
+
print "Preparing project..."
|
69
83
|
|
70
|
-
|
84
|
+
@default_account.save_if_none response.object.fetch("account_id")
|
85
|
+
@default_project.save_if_none response.object.fetch("project_id")
|
86
|
+
@default_region.save_if_none response.object.fetch("region")
|
71
87
|
|
72
|
-
|
73
|
-
|
74
|
-
|
88
|
+
# Fetch credentials for build context upload
|
89
|
+
@deployment_url = response.object.fetch("url")
|
90
|
+
@credentials_response = api.get_deployment_with_delay_and_retry @deployment_url
|
91
|
+
end
|
75
92
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
93
|
+
credentials = @credentials_response.object.fetch("credentials")
|
94
|
+
region = @credentials_response.object.fetch("region")
|
95
|
+
bucket = @credentials_response.object.fetch("bucket")
|
96
|
+
watch_deployment_url = @credentials_response.object.fetch("deployment_url")
|
80
97
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
watch_deployment_url = @credentials_response.object.fetch("deployment_url")
|
98
|
+
Duration.measure do
|
99
|
+
# Upload build context
|
100
|
+
Aws::S3.new(bucket:, region:, credentials:).push @commit
|
85
101
|
|
86
|
-
|
87
|
-
|
88
|
-
|
102
|
+
# Perform deployment
|
103
|
+
api.put_as_json @deployment_url
|
104
|
+
end
|
89
105
|
|
90
|
-
|
91
|
-
api.put_as_json @deployment_url
|
106
|
+
puts "Follow at #{watch_deployment_url}"
|
92
107
|
end
|
93
|
-
|
94
|
-
puts "Follow at #{watch_deployment_url}"
|
95
108
|
end
|
96
109
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Envirobly
|
4
|
+
class Target
|
5
|
+
attr_accessor :account_id, :project_id, :region
|
6
|
+
|
7
|
+
def initialize(
|
8
|
+
default_account_id: nil,
|
9
|
+
default_project_id: nil,
|
10
|
+
default_region: nil,
|
11
|
+
default_project_name: nil,
|
12
|
+
default_environ_name: nil,
|
13
|
+
account_id: nil,
|
14
|
+
project_id: nil,
|
15
|
+
region: nil,
|
16
|
+
project_name: nil,
|
17
|
+
environ_name: nil
|
18
|
+
)
|
19
|
+
@default_account_id = default_account_id
|
20
|
+
@default_project_id = default_project_id
|
21
|
+
@default_region = default_region
|
22
|
+
@default_project_name = default_project_name
|
23
|
+
@default_environ_name = default_environ_name
|
24
|
+
@account_id = account_id
|
25
|
+
@project_id = project_id
|
26
|
+
@region = region
|
27
|
+
@project_name = project_name
|
28
|
+
@environ_name = environ_name
|
29
|
+
end
|
30
|
+
|
31
|
+
def missing_params
|
32
|
+
[].tap do |result|
|
33
|
+
if project_id.blank? && account_id.blank?
|
34
|
+
result << :account_id
|
35
|
+
end
|
36
|
+
|
37
|
+
if project_id.blank? && region.blank?
|
38
|
+
result << :region
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def account_id
|
44
|
+
return if @project_id
|
45
|
+
|
46
|
+
@account_id || @default_account_id
|
47
|
+
end
|
48
|
+
|
49
|
+
def project_id
|
50
|
+
return if @project_id.blank? && (@account_id.present? || @project_name.present?)
|
51
|
+
|
52
|
+
@project_id || @default_project_id
|
53
|
+
end
|
54
|
+
|
55
|
+
def project_name
|
56
|
+
return if @project_id
|
57
|
+
|
58
|
+
@project_name.presence || @default_project_name
|
59
|
+
end
|
60
|
+
|
61
|
+
def environ_name
|
62
|
+
@environ_name.presence || @default_environ_name
|
63
|
+
end
|
64
|
+
|
65
|
+
def region
|
66
|
+
return if @project_id
|
67
|
+
|
68
|
+
@region || @default_region
|
69
|
+
end
|
70
|
+
|
71
|
+
def ignored_params
|
72
|
+
[].tap do |result|
|
73
|
+
if @account_id && @project_id
|
74
|
+
result << :account_id
|
75
|
+
end
|
76
|
+
|
77
|
+
if @project_id && @region
|
78
|
+
result << :region
|
79
|
+
end
|
80
|
+
|
81
|
+
if @project_id && @project_name.present?
|
82
|
+
result << :project_name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/envirobly/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: envirobly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Starsi
|
@@ -194,6 +194,7 @@ files:
|
|
194
194
|
- lib/envirobly/git/commit.rb
|
195
195
|
- lib/envirobly/git/unstaged.rb
|
196
196
|
- lib/envirobly/numeric.rb
|
197
|
+
- lib/envirobly/target.rb
|
197
198
|
- lib/envirobly/version.rb
|
198
199
|
homepage: https://github.com/envirobly/envirobly-cli
|
199
200
|
licenses:
|